[ / / / / / / / / / / / / / ] [ dir / 1917 / arda / cafechan / flutter / had / kocsog / leftpol / senran ][Options][ watchlist ]

/tech/ - Technology

You can now write text to your AI-generated image at https://aiproto.com It is currently free to use for Proto members.
Name
Email
Subject
Comment *
File
Select/drop/paste files here
* = required field[▶ Show post options & limits]
Confused? See the FAQ.
Expand all images

File (hide): ec9b76f3fbfe50c⋯.png (70.43 KB, 695x763, 695:763, aoc 2017.png) (h) (u)

[–]

 No.830716>>830860 >>830958 [Watch Thread][Show All Posts]

Advent of Code is a series of small programming puzzles for a variety of skill levels. They are self-contained and are just as appropriate for an expert who wants to stay sharp as they are for a beginner who is just learning to code. Each puzzle calls upon different skills and has two parts that build on a theme.

http://adventofcode.com/

 No.830717>>830761 >>831825

Day 1 in Rust: https://play.rust-lang.org/?gist=b369f967792ec62e7eb875201ff0a278&version=stable

const INPUT: &[u8] = b"1122";

fn main() {
println!("{}",
INPUT
.iter()
.zip(INPUT[1..].iter().chain(std::iter::once(&INPUT[0])))
.filter(|&(a, b)| a == b)
.map(|(a, _)| (a - b'0') as u32)
.sum::<u32>()
);
}


 No.830756>>831859

Day 1 in C: http://codepad.org/CiFpQwfb

#include <stdio.h>

char INPUT[] = "1122";

int main()
{
unsigned int result = 0;
unsigned int i;
for (i = 0; i < sizeof(INPUT)-1; i++) {
if (INPUT[i] == INPUT[(i+1)%(sizeof(INPUT)-1)]) {
result += INPUT[i] - '0';
}
}
printf("%d\n", result);
return 0;
}


 No.830760>>831859

1 in Python http://codepad.org/gyUmadgj

[code]#!/usr/bin/env python3

INPUT = "1122"

print(sum(map(lambda a, b: int(a) if a == b else 0, INPUT, INPUT[1:]+INPUT[0])))[code]


 No.830761>>830763

>>830717

just noticed that there is a part 2:

const INPUT: &str = "1212";

fn main() {
println!(
"{}",
solve(
INPUT.chars().map(fuck_you_rust_why_are_closures_not_clone),
INPUT.len() / 2
)
);
}

fn fuck_you_rust_why_are_closures_not_clone(c: char) -> u32 {
c.to_digit(10).unwrap()
}

fn solve<I: Clone + Iterator<Item=u32>>(iter: I, step: usize) -> u32 {
iter.clone()
.zip(iter.cycle().skip(step))
.filter(|&(a, b)| a == b)
.map(|(a, _)| a)
.sum()
}


 No.830763>>830767

>>830761

What is part 2? Do I need to log in to see it?


 No.830767

File (hide): 6f1b23e0a902375⋯.png (250.94 KB, 1120x1848, 20:33, Screen Shot 2017-12-01 at ….png) (h) (u)


 No.830769

http://codepad.org/LPJ86RtI

#include <stdio.h>

char INPUT[] = "123425";

int main()
{
unsigned int result = 0;
unsigned int i;
for (i = 0; i < sizeof(INPUT)-1; i++) {
if (INPUT[i] == INPUT[(i+(sizeof(INPUT)-1)/2)%(sizeof(INPUT)-1)]) {
result += INPUT[i] - '0';
}
}
printf("%d\n", result);
return 0;
}

http://codepad.org/cBpouX3o

#!/usr/bin/python3

for INPUT in ["1212", "1221", "123425", "123123", "12131415"]:
print(sum(map(lambda a, b: int(a) if a == b else 0, INPUT, INPUT[int(len(INPUT)/2):]+INPUT)))


 No.830771

PROC advent 1 = (STRING d)INT:
IF LWB d > UPB d THEN 0
ELSE STRING e = d + d[LWB d],
INT sum := 0;
FOR i FROM LWB e TO UPB e - 1 DO
IF e[i] = e[i + 1] THEN sum +:=
IF INT x; char in string(e[i], x, "0123456789"[@0]) THEN x ELSE 0
FI FI OD; sum FI;
printf(($g(0)l$, advent 1("1122"), advent 1("1111"), advent 1("1234"), advent 1("91212129")))


 No.830841

$_=<>;chomp;@a=split//;for(0..$#a){$b+=$a[$_]if$a[($_+1)%$#a]==$a[$_]};print"$b".$/

$_=<>;chomp;@a=split//;for(0..$#a){$b+=$a[$_]if$a[($_+$#a/2)%$#a]==$a[$_]};print"$b".$/


 No.830846>>830866 >>830883 >>830889 >>831095

File (hide): 5b806053916449f⋯.png (6.95 KB, 696x111, 232:37, no.png) (h) (u)


 No.830859

echo 1122 | awk '{split($0,c,"");r=0;for(i=1;i<=length($0);i++){r+=(c[i]==c[i%length($0)+1])?c[i]:0};print r}'

echo 123123 | awk '{split($0,c,"");r=0;for(i=1;i<=length($0);i++){r+=(c[i]==c[(i+length($0)/2-1)%length($0)+1])?c[i]:0};print r}'


 No.830860>>830862 >>830864

>>830716 (OP)

do i get paid or win a job for solving these problems?


 No.830862

>>830860

Look, you're trapped here forever. Solving these is an option to kill your boredom in this shithole and to show off languages.


 No.830864>>830879

>>830860

>Solving these is an option to kill your boredom in this shithole

thats what shitpostings for cunt


 No.830866>>830879

>>830846

>MUUUUUH (((BOTNET)))

have you considered killing yourself?


 No.830879>>830908

>>830864

>>830866

Shut up and code.


 No.830883

>>830846

My thoughts exactly...


 No.830888>>831749 >>831859

I got this in python, nothing fancy:


line = open("input.txt", "r").readline();
acum = 0;
for i in range(0, len(line)):
if line[i - 1] == line[i]:
acum += int(line[i]);
print(acum);


line = open("input.txt", "r").readline();
acum = 0;
for i in range(0, len(line)):
if line[i - len(line) // 2] == line[i]:
acum += int(line[i]);
print(acum);


 No.830889

>>830846

b-but anon there's no other coding challenge sites


 No.830908>>830915 >>830926 >>830944 >>830952 >>831068 >>831075

>>830879

ITT faggots try to broadcast their /tech/ awareness by posting their favourite esoteric languages that AREN'T used in INDUSTRY and then they argue over how 'superior' and 'expressive' their language is. How it will be the industry standard in 5 years. They say they are 'programmers', 'developers', and 'software engineers'. Yet they argue about programming languages instead of ACTUALLY programming. These faggots are more appropriately known as 'LARPers'. LARPers who write shitty code and will be replaced by more experienced streetshitters who write more functional, more maintainable, BETTER code.


 No.830915>>830922

>>830908

$e="u";$a="r";$l="g";$x="o";$c="y";$o="e";$d="a";$s="'";print$c.$x.$e.$s.$a.$o.$".$l.$d.$c.$".$/


 No.830922

>>830915

spd-say -t child_female -p +100 faggot


 No.830924

File (hide): 05a4224dd19cabb⋯.png (92.11 KB, 1264x580, 316:145, 1.png) (h) (u)

Mathematica


 No.830926

>>830908

Lighten up mate, these are only for fun.


 No.830944

>>830908

>maintainable code

>for a Christmas challenge

who cares, faggot


 No.830952

>>830908

Calm down and take your pills. Also

>posting their favourite esoteric languages that AREN'T used in INDUSTRY

C, Python, Perl, Awk aren't used in the industry?


 No.830958>>830961

>>830716 (OP)

>The night before Christmas, one of Santa's Elves calls you in a panic. "The printer's broken! We can't print the Naughty or Nice List!" By the time you make it to sub-basement 17, there are only a few minutes until midnight. "We have a big problem," she says;

>she

into the trash


 No.830961

File (hide): 70c592e859d022d⋯.png (Spoiler Image, 564.71 KB, 744x1052, 186:263, ..png) (h) (u)

>>830958

Here's something to soothe your gay rage


 No.830982>>830997

File (hide): dc63559330b2149⋯.jpg (27.21 KB, 600x425, 24:17, perl-scripts-done.jpg) (h) (u)

Perl (theres a better solution but im tired rn)


use strict;
use warnings "all";

my @data = qw(1 1 2 2);
#my @data = qw(1 1 1 1);
#my @data = qw(1 2 3 4);
#my @data = qw(9 1 2 1 2 1 2 9);

my $sum = 0;

my $last = $data[0];
for (my $i = 1; $i < int (@data + 1); ++$i) {
if ($data[$i % int @data] == $last) {
$sum += $data[$i % int @data];
}
$last = $data[$i];
}

print "$sum\n";


 No.830997

>>830982

Here is the wizard version


use strict;
use warnings "all";

my $d = "1122";
#my $d = "1111";
#my $d = "1234";
#my $d = "91212129";

$d =~ m,^(\d),;
$d .= $1;

my $sum = 0;
while ($d =~ m,(?=(\d)(\d)),g) {
if ($1 == $2) {
$sum += $1;
}
}

print "$sum\n";


 No.831049

C double plus

void inverse_captcha1(std::string input)
{
input.push_back(input[0]);
std::cout << std::inner_product(input.begin(), input.end() - 1, input.begin() + 1,
0, [](int acc, char c){ return acc + c; }, [](char a, char b){ return a == b ? a - '0' : 0; });
}
void inverse_captcha2(std::string input)
{
size_t orig_sz = input.size(), orig_sz2 = orig_sz / 2;
input.resize(3 * orig_sz2);
std::copy_n(begin(input), orig_sz2, begin(input) + orig_sz);
std::cout << std::inner_product(input.begin(), input.begin() + orig_sz, input.begin() + orig_sz2,
0, [](int acc, char c){ return acc + c; }, [](char a, char b){ return a == b ? a - '0' : 0; });
}


 No.831068>>831079


 No.831075

>>830908

friend, you curse the crescent moon for vile acts of light pollution and you forget that the day-star will come around, too.

people using languages that interest them may not be professionals, but they are programmers, and their output is honest - it is clearly what it is.

true LARPing you will find on StackOverflow, where "is X suitable for Y?" will always get an earnest affirmative reply. Some motherfucker, because he likes Clojure a little bit, will cheerfully lay his name and reputation down and try to convince you that Clojure is a good idea for Android development. I have no idea how Clojure fairs today, but five-odd years ago a simple hello world would take multiple seconds just to show itself to the user, and the freshest page on Clojure android development said "we looked at this a year ago and it fucking sucked. Nothing to report since!"


 No.831079>>831085

>>831068

Pajeet, I know you don't understand this concept, but the reason Westerners outcompete you is because us coders love programming, it's much more than a 9-5 job.


 No.831085>>831118

File (hide): 68986de46be2a72⋯.png (170.04 KB, 714x262, 357:131, 13073162.png) (h) (u)

>>831079

>this is what /g/tards actually believe


 No.831091>>831094

you're supposed to change your code in response to changing requirements, so here's the final answer for day 1 rather than multiple code-duplicating answers:

let adv_faggotry s =
let digits = String.length s in
let digit c = int_of_char c - int_of_char '0' in
let same n m = if s.[n] = s.[m] then digit s.[n] else 0 in
let rec loop i acc =
if i < 0 then acc else
let next = (i + digits / 2) mod digits in
loop (i - 1) (same i next + acc)
in loop (digits - 1) 0


 No.831094>>831096 >>831104

>>831091

>ocaml or some shit

>no pattern matching

pajeet


 No.831095>>831097

>>830846

get a throwaway github. it's the best of the bunch.

they fired the safe-space tranny for persistently making real girls uncomfortable


 No.831096>>831106

>>831094

not an argument


 No.831097>>831099 >>831102

>>831095

>github

>$7 silver shekels a month

>"""""""the best""""""""

>not bitbucket

>unlimited free private suppositories


 No.831099>>831101

>>831097

Github is free, you don't have to pay a monthly fee.


 No.831101>>831103

>>831099

You have to pay a monthly fee for private repos.


 No.831102

>>831097

bitbucket changed their icon to a rainbow one (only visible when logged in, oddly) to celebrate some fag shit. It isn't free if you get AIDS, anon.


 No.831103>>831105

>>831101

Yeah but otherwise it's free.


 No.831104>>831114

>>831094

I hope this is more to your taste, anon.

let use_of_toilet s =
let digits = match String.length s with n -> n in
let digit = function
| '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4
| '5' -> 5 | '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9
| _ -> failwith "non-digit found in string" in
let same n m = match s.[n] with
| c when c = s.[m] -> digit s.[n]
| _ -> 0 in
let rec loop i acc =
let next = match (i + digits / 2) mod digits with n -> n in
match i with
| 0 -> acc
| n -> loop (i - 1) (same i next + acc)
in loop (digits - 1) 0


 No.831105>>831130

>>831103

>you have to pay for a private profile

>"it's free"


 No.831106

>>831096

>not an argument

i believe the word you're looking for is "parameter", pajeet


 No.831114

>>831104

it annoys me that this piece of shit rewrite is actually better for not producing bullshit answers:

utop # adv_faggotry "hi there";;
- : int = 112

utop # use_of_toilet "hi there";;
Exception: (Failure "non-digit found in string").
Raised at file "pervasives.ml", line 32, characters 22-33
Called from file "puzzle.ml", line 44, characters 25-36
Called from file "toplevel/toploop.ml", line 180, characters 17-56


 No.831118

>>831085

Let's see your solution Pajeet. I'll even let you write it it Java. I'm excited to see how you'll utilize XML to configure your reusable components.


 No.831130>>831133

>>831105

do you bitch when the cable company doesn't give you free pay-per-view?


 No.831133>>831139

>>831130

>watching tv


 No.831139>>831157

>>831133

<not watching television


 No.831157

>>831139

What do you even watch on television? All the programming is for dumb people. I can see it useful if you like to watch the occasional sporting event but still...


 No.831170

>awarding (((yellow stars))) to people

oy vey!


 No.831173

File (hide): baecf733375fb19⋯.png (54.21 KB, 1214x380, 607:190, 2.png) (h) (u)

Day 2 is up.


 No.831174>>831178

Looking at the solutions on reddit, I was surprised to see so many of them using Rust... but then I suppose that's the typical demographic.


 No.831178>>831181

>>831174

Looking at that it seems people actively compete for time.

I wasn't even aware there is a time component to this. Just thought it was a nice series of challenges.

(also top ranked people apparently use perl/python so rust btfo)


 No.831180

there are A LOT of chinks on the leaderboard


 No.831181>>831182 >>831186

>>831178

I did the 2015 competition, and from what I saw on reddit, there was a guy who would rush to finish the solutions in under 2 minutes, and he built a cult of personality around him just for doing that... and even invited people to watch streams of him coding. Very gay.


 No.831182

>>831181

Very gay indeed. Why can't people just do it for free fun?


 No.831183>>831184

Oh apparently we can create private leaderboards, so we could have an 8/tech/ one, but I think it's gay and not worth doing so. Plus you guys would discover my reddit name and bully me.


 No.831184>>831185

>>831183

>bully me

POST IT!


 No.831185

>>831184

I ugh, don't have an account.


 No.831186>>831187

>>831181

wouldn't you have to stay up until the new challenge goes live? what if you're from some shit country and the new challenge goes live when its 4am for you?

super shitty


 No.831187>>831188

>>831186

It looks like they come out at 0:00 EST, so for people in England (a shit country), they'd have to wake up at 5:00 in the morning to collect magic points.


 No.831188>>831190

>>831187

totally defeats the point of rushing then imo


 No.831190>>831193 >>831195

>>831188

Yeah. Funny enough the number #10 guy used Mathematica.

https://www.reddit.com/r/adventofcode/comments/7h0rnm/2017_day_2_solutions/dqn9gd9/

His part1 is marginally better than mine, but I think his part2 is a bit of a mess. I did both parts in under 5 mins, so I'm sure I could have reached the leaderboard (top 100) if I had started when the puzzle dropped. However, despite the Apple badge, I am not gay.


 No.831193

File (hide): b6eef4514eab75b⋯.jpg (32.83 KB, 488x520, 61:65, 193675592615.jpg) (h) (u)

>>831190

>However, despite the Apple badge, I am not gay.

>apple

>not gay


 No.831195

>>831190

I take that back, my part1 is marginally faster.

I haven't seen anyone using Ada yet.


 No.831196

The J solutions are fucked up. I'm not even sure if I'd want to know that language, I might use it for something.

https://www.reddit.com/r/adventofcode/comments/7h0rnm/2017_day_2_solutions/dqn9mju/


 No.831197>>831198

Multithreaded solution: https://play.rust-lang.org/?gist=a66c52c2c097b90b9aa02b2e5b2e8b20&version=stable

extern crate num_cpus;
extern crate threadpool;
use threadpool::ThreadPool;
use std::sync::mpsc::channel;

fn main() {
let input = vec![
vec![ Some(5), Some(1), Some(9), Some(5) ],
vec![ Some(7), Some(5), Some(3), None ],
vec![ Some(2), Some(4), Some(6), Some(8) ]
];
let nrows = input.len();

let pool = ThreadPool::new(num_cpus::get());
let (tx, rx) = channel::<i32>();

for rows in input {
let tx = tx.clone();
pool.execute(move || {
let mut minmax = None;
for x in rows {
if let Some(y) = x {
if let Some((min, max)) = minmax {
if y > max {
minmax = Some((min, y));
} else if y < min {
minmax = Some((y, max));
}
} else {
minmax = Some((y, y));
}
}
}
if let Some(r) = minmax {
let _ = tx.send(r.1 - r.0);
} else {
let _ = tx.send(0);
}
});
}

println!("{}", rx.iter().take(nrows).sum::<i32>());
}


 No.831198>>831222

>>831197

I don't think the input size necessitates threading anon


 No.831202

I'm waiting for the Enterprise Java and relational database solution.


 No.831203>>831205

Could someone please screenshot part 2?


 No.831205>>831222

File (hide): 46fca6d859ba607⋯.png (370.42 KB, 1764x1372, 9:7, part2.png) (h) (u)


 No.831219

day 2

let checksum_of_matrix m =
let rec difference list low high =
match list with
| [] -> high - low
| n :: rest when n < low -> difference rest n high
| n :: rest when n > high -> difference rest low n
| _ :: rest -> difference rest low high in
let checksum acc list =
match list with
| n :: m :: rest -> acc + difference (m :: rest) n n
| _ -> failwith "row too short"
in
List.fold_left checksum 0 m

(* wtf kind of problem is this *)
let checksum2_of_matrix m =
let rec hasfactor n = function
| [] -> None
| m :: _ when m > n && 0 = (m mod n) -> Some (m / n)
| m :: _ when m < n && 0 = (n mod m) -> Some (n / m)
| _ :: rest -> hasfactor n rest in
let rec omega_x_squared orig = function
| [] -> failwith "no evenly divisible numbers this column"
| n :: rest ->
match hasfactor n orig with
| None -> omega_x_squared orig rest
| Some n -> n
in List.fold_left (fun acc list -> acc + omega_x_squared list list) 0 m
just a string list list for a 'matrix'


 No.831220>>831221 >>831223

>OP shill is copy paste of a paragraph from site and a link

>junk lingo: variety of skill levels, self-contained, appropriate, stay sharp, learning to code, build on a theme

>hey guys blah blah backstory Santa needs you to count the number of vowels in these words

>zero effort leaderboard for who submitted first

perhaps the most plebbit thing on this board


 No.831221

>>831220

>no code

spotted the butthurt LARPer


 No.831222

>>831198

It doesn't necessitate dealing with empty cells and rows either...

>>831205

Thanks!

https://play.rust-lang.org/?gist=62a11d20dbdcdb8e26e66efd08f0a340&version=stable

extern crate itertools;
extern crate num_cpus;
extern crate threadpool;
use itertools::Itertools;
use threadpool::ThreadPool;
use std::sync::mpsc::channel;

fn main() {
let input = vec![
vec![ 5, 9, 2, 8 ],
vec![ 9, 4, 7, 3 ],
vec![ 3, 8, 6, 5 ]
];
let nrows = input.len();

let pool = ThreadPool::new(num_cpus::get());
let (tx, rx) = channel::<i32>();

for row in input {
let tx = tx.clone();
pool.execute(move || {
let pairs = row.iter().combinations(2);
for x in pairs {
if x[0]%x[1] == 0 {
let _ = tx.send(x[0]/x[1]);
} else if x[1]%x[0] == 0 {
let _ = tx.send(x[1]/x[0]);
}
}
});
}

println!("{}", rx.iter().take(nrows).sum::<i32>());
}


 No.831223

>>831220

say what you want about the leaderboard but the digimon christmas story isn't bad


 No.831227>>831230 >>831240


 No.831230>>831231 >>831234

>>831227

I didn't want to taint my system with rust just to compare. How about perf? The second day 2 solution, compiled with ocamlopt and run from shell, overhead and all:

 Performance counter stats for './p':

1,709,370 cycles
1,534,798 instructions # 0.90 insn per cycle

0.000723235 seconds time elapsed


 No.831231

>>831230

that's run as: sudo perf stat -e cycles -e instructions ./p

I don't use perf much, just copying someone who uses it


 No.831234>>831235

>>831230

I just included the time to show that it runs <1ms (which is a requirement of aoc. read the lore). my solution isn't meant to be the fastest also the timing was taken on play.rust-lang.org not on my pc.


 No.831235>>831236

>>831234

There is no hard requirement on performance you LARPfag.


 No.831236>>831238

>>831235

>When your eyes can focus again, everything seems a lot more pixelated than before. She must have sent you inside the computer! You check the system clock: 25 milliseconds until midnight. With that much time, you should be able to collect all fifty stars by December 25th.

>Collect stars by solving puzzles. Two puzzles will be made available on each day millisecond in the advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!


 No.831238>>831240 >>831241

File (hide): c808e5ad01a35ca⋯.jpg (48.71 KB, 977x720, 977:720, 15982543.jpg) (h) (u)

>>831236

Are you just pretending to be retarded?


 No.831240>>831242 >>831244 >>831272

>>831227

i removed loops: https://play.rust-lang.org/?gist=4628d63c3e21ea1cc42f847ced908dfc

Time: 0.028 ms

>>831238

>le smug aniuuuuh

shit. you won. i am sooooooo mad now.


 No.831241

>>831238

he just doesn't want to compare rust against ocaml for no reason

meanwhile:

$ time python -c 'print 1'
1

real 0m0.039s
user 0m0.023s
sys 0m0.004s

oh no! christmas is ruined!

tbh I'm not thrilled about getting microbenchmarks working yet under ocaml. Fucking Jane Street changed their tool and the only documentation was the blog for the old version.


 No.831242>>831243

>>831240

>there is no hard requirement on performance

>posts some part of the shitty lore that accompanies the challenges

If there were a hard requirement on performance you would have to submit your solution and it would only be accepted if it met the requirement.

It's my fault though for expecting a rustfag to be smart.


 No.831243

>>831242

>muh hard requirement

Please quote me where i said that.

>rustfag

Found the triggered anti Rust shill. Post code or kill yourself.


 No.831244>>831246

>>831240

Do I get those numbers when I log in? I bet your code runs in a fraction of that time if you don't parse the numbers from a string.


 No.831246>>831248 >>831249

>>831244

>Do I get those numbers when I log in?

Yes

>I bet your code runs in a fraction of that time if you don't parse the numbers from a string.

But the parsing is part of the challenge.


 No.831248>>831250

>>831246

>But the parsing is part of the challenge.

It really isn't.

The only goal is to solve the challenge. If you happen to be a burger you can compete for how fast you solve but that's all.


 No.831249

>>831246

how is Mr. Excel programmer supposed to take part then? The obvious way for him to start would be to put today's data in a sheet.

of course for comparison purposes if your inputs are all in the program a cheaty enough compiler could reduce it to a single write() syscall of a static buffer to standard out, with zero calculation.


 No.831250>>831251

>>831248

No it is part of the challenge. Read the lore. You were sent into the computer.

>The night before Christmas, one of Santa's Elves calls you in a panic. "The printer's broken! We can't print the Naughty or Nice List!" By the time you make it to sub-basement 17, there are only a few minutes until midnight. "We have a big problem," she says; "there must be almost fifty bugs in this system, but nothing else can print The List. Stand in this square, quick! There's no time to explain; if you can convince them to pay you in stars, you'll be able to--" She pulls a lever and the world goes blurry.


 No.831251>>831252

>>831250

that implies the opposite of "you must do parsing". You're inside a computer. You could just be handed a pointer to a data structure for each of the problems so far.


 No.831252

>>831251

>content-type : text/plain

No I receive my input over HTTP.


 No.831253>>831254

File (hide): ce97009f93faa2b⋯.gif (972.85 KB, 256x186, 128:93, 1406289146470.gif) (h) (u)

fucking hell this autism


 No.831254

>>831253

Don't worry. I am merely pretending to be retarded.


 No.831271>>831279 >>831280


$*IN.lines.map({[-] .comb(/\d+/).map(+*).minmax.bounds.reverse}).sum.say


$*IN.lines.map({[/] .comb(/\d+/).combinations(2).map({.sort(-*)}).first({$_[0]%%$_[1]})}).sum.say


 No.831272


 No.831279>>831280

>>831271

Horrifying indeed. What language is this?


 No.831280>>831287

>>831271

>>831279

On second thought, is this perl6? It better not be.


 No.831287>>831289

>>831280

yes, it's perl6.


 No.831289>>831306 >>831311

>>831287

Does it still have worse performance than perl5?


 No.831306>>831312

>>831289

probably. it's abysmal in every other way. the primary outreach strategy of "try to appeal to little girls" (no really) hasn't worked out for it yet.


 No.831311>>831545

Yesterdays problem:


my$a=get.comb.list;zip($a.list,$a.rotate(1)).map({$_[0]==$_[1]&&$_[0]}).sum.say


my$a=get.comb.list;zip($a.list,$a.rotate($a.elems/2)).map({$_[0]==$_[1]&&$_[0]}).sum.say

>>831289

It's slow as shit


 No.831312>>831316

>>831306

Holy shit what? Perl is a stinking camel, not a girly butterfly. I'd upload screenshots for you so you don't have to click, but I can't.

From https://perl6.org/:

>Hi, my name is Camelia. I'm the spokesbug for Perl 6, the plucky little sister of Perl 5. Like her world-famous big sister, Perl 6 intends to carry forward the high ideals of the Perl community. Perl 6 is currently being developed by a team of dedicated and enthusiastic volunteers. You can help too. The only requirement is that you know how to be nice to all kinds of people (and butterflies). Go to #perl6 (irc.freenode.net) and someone will be glad to help you get started.


 No.831316

>>831312

The butterfly was perl6's biggest mistake apart from the god awful shit tier performance.

Perl5 is incredibly fast, especially for anything string related but number crunching is not too bad either.


 No.831319>>831322 >>831326


 No.831322>>831323

>>831319

While these posts are incredibly shitty there are some true aspects to them.

>people shit on you when you try to learn

>stick with it and git gud

>eventually you also shit on noobs

the cycle never ends


 No.831323

>>831322

Forgot to say that these blogposts are linked on perl6.org in one of those useless categories on the top.


 No.831325>>831372

i kinda like how terse perl6 can be but all this faggotry surrounding the language is unbearable


 No.831326

>>831319

>Ignoring trolls and people whose knowledge of Perl ends with the line-noise quips, Perl is the Grandfather of Web, the Queen of Backwards Compatibility, and Gluest language of all the Glues. Perl is installed by default on many systems, and if you're worthy enough to wield its arcane magic, it's quite damn performant.

>Rakudo language, on the other hand, is none of those things.

Hey guys we're not even as performant as a terrible scripting language, but we have really good support for using invisible non-whitespace unicode operators.

... hey, where are you going? I work in marketing! Come back! It's not like 'concise and fast' is an option anyway right? ha ha!


 No.831372>>831552

>>831325

Learn J or K.


 No.831481

PROC difference = ([]INT a)INT:
(INT low := max int, hi := 0;
FOR i FROM LWB a TO UPB a DO INT x = a[i];
IF x < low THEN low := x FI;
IF x > hi THEN hi := x FI OD;
hi - low),
checksum = ([][]INT a)INT:
IF LWB a > UPB a THEN 0 ELSE difference(a[@1][1]) + checksum(a[@1][2:]) FI;
printf(($g(0)l$,
checksum(
((5,1,9,5),
(7,5,3),
(2,4,6,8)))))


 No.831524>>831525

i'm doing this to learn pony, first day:


use "cli"

actor Main
new create(env: Env) =>
let cs =
try
CommandSpec.leaf("decaptia", "do level 1 of adventofcode", [
OptionSpec.i64("offset",
"offset of number to compare to."
where short' = 'o', default' = 1)
OptionSpec.i64("percent",
"offset of a percent of the the seq len. as a floatpoint number."
where short' = 'p', default' = 0)
], [
ArgSpec.string_seq("seq",
"the captcha sequenc to evaluate")
])? .> add_help()?
else
env.exitcode(-1) // some kind of coding error
return
end

let cmd =
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
return
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
return
end


let seq: String = try
cmd.arg("seq").string_seq().apply(0)?
else "0"
end

var sum: ISize = 0
var pos: ISize = 0
let size = seq.size().isize()

let percent = cmd.option("percent").i64().isize()
let offset = if percent > 0 then
((size * percent)/ 100)
else
cmd.option("offset").i64().isize()
end

repeat
try
let char = seq(pos.usize())?
if char == seq(((pos + offset) % size).usize())? then
sum = sum + char.isize() + -48
end
end
pos= pos + 1
until pos >= size end
env.out.print("mew")
env.out.print(sum.string())


 No.831525>>831557

>>831524

and second day:

use "cli"
use "files"
use "debug"

actor Main
var matrix: Array[Array[I32]]= []
let env: Env

new create(env': Env) =>
env= consume env'
let cs =
try
CommandSpec.leaf("decaptia", "do level 2 of adventofcode", [
OptionSpec.string("file",
"What file is the input in"
where short' = 'f', default' = "./input")
OptionSpec.bool("mod",
"devide the two numbers that evenly modulo"
where short' = 'm', default' = false)
], [
ArgSpec.string_seq("",
"leftover arguments")
])? .> add_help()?
else
env.exitcode(-1) // some kind of coding error
return
end


let cmd =
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
return
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
return
end


try
let path = FilePath(
env.root as AmbientAuth,
cmd.option("file").string()
)?

match OpenFile(path)
| let file: File =>
for line in FileLines(file) do
var temp_array: Array[I32] = []
for item in line.string().split().values() do
temp_array.push(
try item.i32()? else I32(0) end
)
end
matrix.push(temp_array)
end
else
env.err.print("Error opening file ")
end
end


env.out.print("...")
if cmd.option("mod").bool() then
env.out.print(mod_matrix().string())
else
env.out.print(sum_matrix().string())
end


fun mod_matrix() :I32 =>
var mod: I32= 0
for line in matrix.values() do
var pos: USize= 0
let mod' = mod
repeat
let i = try line(pos)? else I32(0) end
var pos' = pos+ 1
repeat
let q = try line(pos')? else I32(0) end
mod = mod + (
match I32(0)
| (i % q) => i / q
| (q % i) => q / i
else 0 end
)
Debug(pos.string() + " " + pos'.string())
//Debug(mod.string() + " " + mod'.string())
until (pos' = pos' + 1) >= line.size() end
until (pos = pos + 1) >= line.size() end
Debug(mod)
end
mod


fun sum_matrix() :I32 =>
var sum: I32= 0
for line in matrix.values() do
var min = I32.max_value()
var max = I32.min_value()
for item in line.values() do
let temp = item.i32()
if temp > max then max = temp end
if temp < min then min = temp end
end
Debug(min.string() + " " + max.string())
sum = sum + (max-min)
end
sum


 No.831545

>>831311

Now do it in a real language (like C)


 No.831552

>>831372

J advantage:

>KEI worked on it

>Jsoftware likes you

J disadvantage:

>more APL-like in a bad way

>Roger's gone, working for APL company now. deadlang?

K advantage:

>good syntax

>lot of good design

>open-source implementations [because Kx hates you and hid away their version after it caught popularity]

K disadvantage:

>Kx hates you fucking LARPers. Go jump off a bridge, nerd

>no KEI, no J labs, no books, impoverished red-headed stepchild lang


 No.831557

>>831525

no data races and no deadlocks?

that's interesting and all...

but the name of the language is pony

nothing good can come of this

also 'else' (without 'if') in that pattern-matching, gross. Somehow it looks a lot like Java.


 No.831584>>831702 >>832051 >>833996 >>834007

Today's thing + some miscellaneous machinery to ease future parsing

using namespace std;

template<typename P> constexpr bool grab_while(string_view in, string_view& out, size_t& cur, P&& p)
{
if (cur >= in.size()) return false;
size_t start = cur;
if (p(in[cur])) do ++cur; while(cur < in.size() && p(in[cur]));
out = string_view(in.data() + start, cur - start);
return true;
}
template<typename P> struct split_iter
{
constexpr bool operator!=(nullptr_t) { grab_while(in, out, cur, not_fn(p)); return grab_while(in, out, cur, p); }
constexpr string_view operator*() const { return out; }
constexpr void operator++() const {}
string_view in, out; size_t cur; P p;
};
template<typename P> struct split_t
{
constexpr auto begin() const { return split_iter<P>{sv, string_view(), 0, p}; }
constexpr auto end() const { return nullptr; }
string_view sv; P p;
};
template<typename P> constexpr auto split(string_view sv, P&& p) { return split_t<P>{sv, forward<P>(p)}; }
template<typename P> constexpr auto split(P&& p) { return [p = forward<P>(p)](string_view sv){ return split(sv, p); }; }
template<typename Rit, typename F> struct map_to_iter
{
template<typename T> constexpr bool operator!=(T&& t) { return it != t; }
constexpr auto operator*() const { return f(*it); }
constexpr void operator++() const { ++it; }
Rit it; F f;
};
template<typename R, typename F> struct map_to_t
{
constexpr auto begin() const { return map_to_iter<decltype(r.begin()), F>{r.begin(), f}; }
constexpr auto end() const { return r.end(); }
R r; F f;
};
template<typename R, typename F> constexpr auto map_to(R&& r, F&& f) { return map_to_t<R, F>{forward<R>(r), forward<F>(f)}; }
template<typename F> constexpr auto map_to(F&& f) { return [f = forward<F>(f)](auto&& r){ return map_to(forward<decltype(r)>(r), f); }; }
template<typename A, typename B> constexpr auto operator|(A&& a, B&& b) { return forward<B>(b)(forward<A>(a)); }

void corruption_checksum1(string input)
{
auto sum = 0u;
for (string_view line : input | split([](char c){ return c != '\n'; })){
auto minv = ~0u, maxv = 0u;
for (unsigned int v : line | split([](char c){ return !isspace(c); }) | map_to([](auto w){ return stoul(string(w)); }))
minv = min(minv, v), maxv = max(maxv, v);
sum += maxv - minv;
}
cout << sum;
}
void corruption_checksum2(string input)
{
auto sum = 0u; vector<unsigned int> prev;
for (string_view line : input | split([](char c){ return c != '\n'; })){
for (unsigned int v : line | split([](char c){ return !isspace(c); }) | map_to([](auto w){ return stoul(string(w)); })){
bool inv = false;
if (auto it = find_if(prev.begin(), prev.end(), [&](auto p){ return !(p % v) || (inv = !(v % p)); }); it != prev.end()){
sum += inv ? v / *it : *it / v;
break;
}
prev.push_back(v);
}
prev.clear();
}
cout << sum;
}


 No.831702>>831751

>>831584

Parallelized version of day 2

vector<string_view> regroup_lines(string_view input)
{
const size_t n_thr = omp_get_max_threads();
vector<string_view> groups; groups.reserve(n_thr);
const size_t approx_group_sz = input.size() / n_thr;
size_t start = 0;
for (size_t i = approx_group_sz, j = 0; j < n_thr - 1; start = i, i += approx_group_sz, ++j){
for (; input[i - 1] != '\n'; ++i) ;
groups.emplace_back(&input[start], i - start);
}
groups.emplace_back(&input[start], input.size() - start);
return move(groups);
}
void corruption_checksum1_parallel(string input)
{
vector<string_view> subinput = regroup_lines(input);
auto sum = 0u;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < omp_get_max_threads(); ++i)
for (string_view line : subinput[i] | split([](char c){ return c != '\n'; })){
auto minv = ~0u, maxv = 0u;
for (unsigned int v : line | split([](char c){ return !isspace(c); }) | map_to([](auto w){ return stoul(string(w)); }))
minv = min(minv, v), maxv = max(maxv, v);
sum += maxv - minv;
}
cout << sum;
}
void corruption_checksum2_parallel(string input)
{
vector<string_view> subinput = regroup_lines(input);
auto sum = 0u;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < omp_get_max_threads(); ++i){
vector<unsigned int> prev;
for (string_view line : subinput[i] | split([](char c){ return c != '\n'; })){
for (unsigned int v : line | split([](char c){ return !isspace(c); }) | map_to([](auto w){ return stoul(string(w)); })){
bool inv = false;
if (auto it = find_if(prev.begin(), prev.end(), [&](auto p){ return !(p % v) || (inv = !(v % p)); }); it != prev.end()){
sum += inv ? v / *it : *it / v;
break;
}
prev.push_back(v);
}
prev.clear();
}
}
cout << sum;
}


 No.831746>>831747

man. day. day 3. just.

just.

let nextoddroot n =
let iseven n = 0 = n mod 2 in
let root = 1 + int_of_float (sqrt (float n)) in
let root' = if iseven root then root + 1 else root in
root' * root'

let move (x, y) (dx, dy) = (x + dx, y + dy)

let turn_left p = match p with
| (1, 0) -> (0, -1)
| (0, -1) -> (-1, 0)
| (-1, 0) -> (0, 1)
| (0, 1) -> (1, 0)
| _ -> failwith "Invalid delta"

let dump_matrix m =
let dim = Array.length m - 1 in
let width = String.length (string_of_int (Array.get (Array.get m dim) dim)) + 1 in
Array.iter (fun row ->
Array.iter (Printf.printf "%*d " width) row;
print_newline ()) m

let rec drift m (x, y) delta v n =
let row = Array.get m y in
Array.set row x v;
match n with
| 0 -> (x,y)
| _ -> drift m (move (x,y) delta) delta (v + 1) (n - 1)

let spiral n =
let dim = int_of_float (sqrt (float (nextoddroot n))) in
let n' = dim * dim in
let half = dim / 2 in
let m = Array.make_matrix dim dim 0 in
let rec loop p d v n =
if (v + n) > n' then let _ = drift m p d v (n - 1) in m else
let p' = drift m p d v n in
let d' = turn_left d in
let v' = v + n in
let p'' = drift m p' d' v' n in
loop p'' (turn_left d') (v' + n) (n + 1)
in
loop (half, half) (1, 0) 1 1

let coord_of_int m n =
let length = Array.length m in
let rec loop row i =
let rec loop' j =
if j = length then loop (Array.get m (i + 1)) (i + 1) else
let n' = Array.get row j in
if n = n' then (j, i) else loop' (j + 1) in
loop' 0
in loop (Array.get m 0) 0

let omgwtf n =
let m = spiral n in
let origin = Array.length m / 2 in
let (x, y) = coord_of_int m n in
abs (x - origin) + abs (y - origin)
part 2 is the above with a redefinition of drift:
let spy_target = ref 0

let spy_found = ref false

let looking_for n =
spy_found := false;
spy_target := n

let sum_of_neighbors m x y =
let sum = safe_get m (x - 1) y +
safe_get m (x + 1) y +
safe_get m x (y - 1) +
safe_get m x (y + 1) +
safe_get m (x - 1) (y - 1) +
safe_get m (x - 1) (y + 1) +
safe_get m (x + 1) (y - 1) +
safe_get m (x + 1) (y + 1) in
(if not !spy_found then
if sum > !spy_target then
(spy_target := sum;
spy_found := true));
if sum = 0 then 1 else sum

let rec drift m (x, y) delta v n =
let row = Array.get m y in
Array.set row x (sum_of_neighbors m x y);
match n with
| 0 -> (x,y)
| _ -> drift m (move (x,y) delta) delta (v + 1) (n - 1)

let wtfbbq n =
looking_for n;
let _ = spiral n in
(!spy_found, !spy_target)


 No.831747

>>831746

oh and safe_get:

let safe_get m x y =
try
Array.get (Array.get m y) x
with
Invalid_argument _ -> 0


 No.831749>>831753

>>830888

>semicolons

????????


 No.831751>>832200

>>831702

day 3 in ye olde C++. I'm sure it must be possible to do part 2 while allocating less memory (i.e. in a deque, push back newest values, remove old values from front), but I'm lazy.

void spiral_memory1(size_t pos)
{
if (!--pos) return cout << 0, void();
for (size_t i = 0, j = 0;; i += 8, j += i)
if (j >= pos){
size_t lvl = i >> 3,
lvl_start = j + 1 - i,
lvl_pos = pos - lvl_start,
lvl_on_side = lvl_pos % (i >> 2),
half_side = i >> 3;
int lvl_side_dist = (int)lvl_on_side - half_side + 1;
return cout << lvl + (lvl_side_dist < 0 ? -lvl_side_dist : lvl_side_dist), void();
}
}
void spiral_memory2(size_t val)
{
size_t upper_bound_sz = [&]{
for (size_t i = 0, j = 0;; i += 8, j += i)
if (j >= val) return 3 + (i >> 2);
}(), upper_bound_sz2 = upper_bound_sz >> 1;
vector<size_t> grid(upper_bound_sz * upper_bound_sz);
auto at = [&](int x, int y){ return upper_bound_sz2 + x + upper_bound_sz * (upper_bound_sz2 + y); };
grid[at(0, 0)] = 1;
for (int x = 1, y = 1, side = 2;; ++x, ++y, side += 2){
for (auto [dx, dy] : {pair(0, -1), pair(-1, 0), pair(0, 1), pair(1, 0)}){
int counter = 0; do {
x += dx; y += dy;
if (size_t newval = (grid[at(x, y)] = [&]{
size_t sum = 0;
for (int j = y - 1; j <= y + 1; ++j)
for (int i = x - 1; i <= x + 1; ++i)
sum += grid[at(i, j)];
return sum;
}()); newval > val)
return cout << newval, void();
} while (++counter < side);
}
}
}


 No.831753

>>831749

they're completely unnecessary in JavaScript except to disambiguate 1 common and 1 rare case, but everyone uses them all the time.

why not in Python too? Just because no big names have told you that the interpreter uses a scaaary yet simple and deterministic algorithm?


 No.831763>>831767

>day 3 solutions look like utter shit

>no neat tricks to make code tidy, it's always going to look like shit because there's no elegant way to do this

cool


 No.831767>>831769

>>831763

did it in OCaml 'cause I'm learning it. but this turtle graphics nonsense I'd rather just do in Forth.

looking at reddit, there is an 'elegant' solution in abusing a mathematical property of the spiral, but that just leaves you with some code that's so optimized for the exact solution that you have to throw it away when it's change.

One thing I do like about this contest is that it gives you a problem and then changes it up, just to break hyper-optimized replies like that.

In the real world I've had a manager tell me he doesn't want a third-party component of some complex software to round a float in a certain way and I was like, uh, shit, I'll get back to you. Flexibility matters.


 No.831769

>>831767

e.g. rustfag:

>It was also kind of unfortunate that my solution for the first part was completely useless for the second part.


 No.831798>>831801 >>832043

I'm not proud. https://play.rust-lang.org/?gist=e075c3521573c8c2c36d8316f0b096e6&version=stable

const INPUT: u32 = 123456;

fn part1() {
let mut s = 1;
let mut x = 0;
let mut y = 0;
let mut dx = 1;
let mut dy = 1;
'b: loop {
for _ in 0..dx {
if s == INPUT {
break 'b;
}
x += dx%2*2-1;
s += 1;
}
dx += 1;
for _ in 0..dy {
if s == INPUT {
break 'b;
}
y += dy%2*2-1;
s += 1;
}
dy += 1;
}
println!("{}", (x as i32).abs()+(y as i32).abs());
}

fn part2() {
fn get(x: i32, y: i32) -> u32 {
if x == 1 && y == 0 {
1
} else if x == y {
if x == 0 {
1
} else if x > 0 {
get(x, y-1) + get(x-1, y-1)
} else {
get(x, y+1) + get(x+1, y+1)
}
} else if -x == y {
if x < 0 {
get(x+1, y) + get(x+1, y-1)
} else {
get(x-1, y) + get(x, y+1) + get(x-1, y+1)
}
} else if x-1 == -y && y < 0 {
get(x-1, y) + get(x-1, y+1)
} else if x-1 == -y && y > 0 {
get(x+1, y) + get(x+1, y-1) + get(x, y-1)
} else if y-1 == x && x < 0 {
get(x, y+1) + get(x+1, y+1) + get(x+1, y)
} else if x-1 == y && y < 0 {
get(x-1, y) + get(x-1, y+1) + get(x, y+1) + get(x+1, y+1)
} else if x == y+1 && y > 0 {
get(x-1, y) + get(x-1, y-1) + get(x, y-1)
} else if x > y.abs() {
get(x, y-1) + get(x-1, y+1) + get(x-1, y) + get(x-1, y-1)
} else if y >= x.abs() {
get(x-1, y-1) + get(x, y-1) + get(x+1, y-1) + get(x+1, y)
} else if y.abs() < -x {
get(x, y+1) + get(x+1, y+1) + get(x+1, y) + get(x+1, y-1)
} else {
get(x-1, y) + get(x-1, y+1) + get(x, y+1) + get(x+1, y+1)
}
}
let mut x = 0;
let mut y = 0;
let mut dx = 1;
let mut dy = 1;
'b: loop {
for _ in 0..dx {
if get(x, y) > INPUT {
break 'b;
}
x += dx%2*2-1;
}
dx += 1;
for _ in 0..dy {
if get(x, y) > INPUT {
break 'b;
}
y += dy%2*2-1;
}
dy += 1;
}
println!("{}", get(x, y));
}

fn main() {
part1();
part2();
}


 No.831801

File (hide): c76db1c59ab13eb⋯.jpg (384.3 KB, 1400x933, 1400:933, steve klabnik2.jpg) (h) (u)

>>831798

Damn. I just want to say that this isn't me.


 No.831823>>831824 >>831825 >>831945

Question about the day1 challenge partA

What should this testcase return?

>9919999


 No.831824>>831945


 No.831825>>831827

>>831823

just change the input here: >>830717


 No.831827>>831828 >>831834 >>831858

>>831825

I tested a C and a Python version from further up and they both returned 36


 No.831828>>831829 >>831834

>>831827

well they are wrong


 No.831829>>831857

>>831828

The rust one returns 45 so it works fine but those other anons fucked it up.

>using C

>using Python

confirmed for shit i guess


 No.831834>>831859


 No.831835

is there an 8chan private leaderboard yet?


 No.831857

>>831829

ocaml's fine though:

utop # sum_faggotry "9919999";;
- : int = 45
utop # sum_matching 9919999;;
- : int = 45


 No.831858>>831859

>>831827

101 is supposed to match the two 1's together, because it's supposed to loop around. C and Python versions don't do that. I guess the single challenge case happened to not use that rule, but one of the examples asked for it.


 No.831859

>>831858

But the versions in >>830756 and >>830760 do and they give the correct output, see >>831834

>>830888 seems to wrap too.


 No.831881>>831990

Fucking WEW! Day 3 is absolute cancer. I first wrote some horrible spaghetti code that worked but took a few milliseconds.

So I rewrote it. Part 1 is now O(1). No idea (and no desire to figure out) how to optimize Part 2.

https://play.rust-lang.org/?gist=2092de6b3ca8df308960c83b7073b7c5

Time: 0.04 ms


 No.831907>>831914 >>831918

LOL

it's so lame to post spoilers before the thing officially ended

sage


 No.831914

>>831907

what..?


 No.831918

>>831907

nodev LARPer spotted

antisage btw


 No.831943>>831961

File (hide): 00fbc31afabaf7a⋯.png (68.34 KB, 804x678, 134:113, p1.png) (h) (u)

File (hide): 373b235a19dc5f0⋯.png (98.24 KB, 984x782, 492:391, p2.png) (h) (u)

Straight and to the point, gets the job done. Only 'clever' part is exploiting properties of complex numbers.


 No.831945


 No.831961>>831964

>>831943

>complex numbers

Nigga what the fuck? How are complex numbers even remotely necessary here?


 No.831964>>831965 >>831985

>>831961

To keep track of both the position and direction, the real and imaginary parts are the x and y coordinates respectively. So -1,-2i is left once, and down twice.

What makes them nice for this (instead of a vector) is that multiplication by i is a right angle rotation.


 No.831965>>831973

>>831964

Yeah I know that. But why are you using complex numbers for this specifically? It is retarded overengineering.

All you need to do is rotate a 2d vector by 90 degrees. If you can't figure out how to do this without complex numbers you should kys.


 No.831973

>>831965

> overengineering

That word doesn't mean what you think it does. They're equivalent.


 No.831985>>831986 >>831987

>>831964

This is quite bad because I am sure you're doing it in floating point and converting back and forth burns CPU and may give inaccurate results once numbers grow big enough


 No.831986>>831987

>>831985

it could be useful in code golf though


 No.831987>>831994

>>831985

>because I am sure you're doing it in floating point

It isn't floating point, it is using exact numbers. There is no converting back/forth until the end, and even that is done exactly.

> burns CPU

Being a symbolic language, mathematica operates a bit differently in being as general as possible, so even something like (+) could be used to do arithmetic with photos of arbitrary symbols, generality carries a performance penalty. For performance sensitive operations, you can Compile blocks of code to optimize for a specific type. For these day 3 cases, both completed in mere milliseconds.

>>831986

> code golf though

Of course.


 No.831990>>831993

>>831881

Wew, didn't think HashMaps were fast. My recursive solution for day 3 part 2 takes 30ms minimum.

New solution in Bash:

INPUT=1337; for row in `wget -q -O- https://oeis.org/A141481/b141481.txt | grep -v "^#" | cut -f2 -d' '`; do if [ $row -gt $INPUT ]; then echo $row; break; fi; done


 No.831993

>>831990

Part 3 converges to a solution really quickly though, those numbers add up very fast. My one completed in under a millisecond.

> 0.000895 Seconds


 No.831994

>>831987

forgot that it's mathematica

Stallman does not approve it


 No.832011>>832214

Day 3 is just straight up a math problem not a programming problem.


 No.832043

File (hide): 7dc71ccaffbf325⋯.jpg (1.39 MB, 1518x1372, 759:686, Judenstern_JMW.jpg) (h) (u)

>>831798

Here is your goldstar, you earned it champ


 No.832051>>832095

File (hide): c3ed4e9ab31be85⋯.jpg (132.29 KB, 1920x1080, 16:9, 1940127171.jpg) (h) (u)

>>831584

c++ was a mistake


 No.832095

>>832051

Why, because I showed a bunch of library-ish things that would normally be hidden behind a header file? It makes the actual important code (the "corruption_checksum" functions) look better than if I did parsing manually and more efficient than if I used stringstreams, and that's all that matters.

Not that I would mind having a more elegant way to do these sorts of range transformations, but hopefully coroutines and view adaptors will fix that when they get in C++20.


 No.832200>>832206

>>831751

day 4. Easy enough.

void high_entropy_passphrases1(string input)
{
size_t valid = 0;
for (string_view phrase : input | split([](char c){ return c != '\n'; })){
unordered_set<string_view> words;
for (string_view word : phrase | split([](char c){ return !isspace(c); }))
if (auto it = words.find(word); it != words.end())
goto next_phrase;
else
words.insert(word);
++valid;
next_phrase:;
}
cout << valid;
}
void high_entropy_passphrases2(string input)
{
size_t valid = 0;
for (string_view phrase : input | split([](char c){ return c != '\n'; })){
unordered_set<string> fingerprints;
for (string_view word : phrase | split([](char c){ return !isspace(c); })){
string fingerprint(26, '\0');
for (char letter : word)
++fingerprint[letter - 'a'];
if (auto it = fingerprints.find(fingerprint); it != fingerprints.end())
goto next_phrase;
else
fingerprints.insert(fingerprint);
}
++valid;
next_phrase:;
}
cout << valid;
}


 No.832206>>832210

>>832200 (checked)

let sorted_array_of_string s =
let len = String.length s in
let a = Array.make len ' ' in
for i = 0 to len - 1 do
a.(i) <- s.[i]
done;
Array.fast_sort (fun a b -> if a = b then 0 else if a > b then 1 else -1) a;
a

let valid_passphrase s =
let seen = Hashtbl.create 10 in
let rec loop list =
match list with
| [] -> true
| w :: rest ->
match Hashtbl.find_opt seen w with
| None ->
Hashtbl.add seen w ();
loop rest
| (Some _) -> false
in loop (List.map sorted_array_of_string (String.split_on_char ' ' s))

let valid_passphrases () =
List.fold_left (fun count phrase -> if valid_passphrase phrase then count + 1 else count)
0
(String.split_on_char '\n' passphrases)
part 1 is just this without the List.map (storing strings instead of sorted arrays of char). 'passphrases' is just a copy&paste of the phrases from the website, in a string

feels like the language is missing a Bytes.sort , though it's a pretty rare thing to want, and more obviously a string_to_array which I had to do manually here.


 No.832209>>832211 >>832213

Day 4 is pure cancer. It's completely trivial and after I do both stars it in hurry, I see that another 300 people also got up early and did it faster.

I hoped for problems which, at least, require some thinking. Like day 3 at the very least.


 No.832210>>832217

>>832206

too much typing


import re
ws = re.compile(r'\s+')
def parse_row(l):
return tuple(filter(None, ws.split(l)))
with open('input.txt', 'r') as f:
lines = tuple(filter(None, map(parse_row, f)))
i = 0
for l in lines:
l = tuple(map(lambda x: ''.join(x), map(sorted, l)))
h = set(l)
if len(h) == len(l):
i += 1
print(i)


 No.832211

>>832209

the leaderboard system is designed to suck.

just collect your yellow stars m8


 No.832213>>832216

>>832209

If I recall the previous years, things do get harder later.


 No.832214

>>832011

>excuses


 No.832216

>>832213

well, then day 4 should have been harder than 3.

maybe it's just one error, I dunno.


 No.832217>>832220

>>832210

valid_passphrase exits early with false on the first repeat. It could also exit early without doing sorted_array_of_string to, at the cost of being a little bit longer. explicit tail-recursive loops are more verbose but more flexible than higher-order functions (news at 11).

it's true that sorted_array_of_string adds a lot of length that I already said a better stdlib shouldn't need (anyone doing adventofcode with Core?)

btw python4 in 2019 will break the entire language because Guido will think by then that 'return' should have mandatory parentheses.


 No.832220>>832221

>>832217

optimization is not needed here though

and when it's needed, Rust > Haskell :)


 No.832221>>832222 >>832236 >>832301

>>832220

>Haskell

... good on you for not even knowing what Haskell looks like

it's OCaml. It's a language you can use for throwaway scripts and also for serious if-this-breaks-I-am-not-even-fired-because-my-employers-are-out-of-business projects. It has a very large 'dynamic range' according to Jane Street devs so instead of saying "I'll do this unimportant thing in Python and then rewrite it in Rust" you can just say "I'll do this in OCaml".


 No.832222>>832234 >>832368

>>832221

Haskell, from reddit

valid pass = length (nub $ sort pass) == length pass
main = interact $ (++"\n") . show . length . filter valid . map words . lines
part 2:
valid pass = length (nub $ sort $ map sort pass) == length pass
I'd rather deal with golfed perl. Just disgusting.


 No.832223

Here's someone doing it with Core (alternate stdlib for OCaml):

open Core

let all_unique_words words =
let set = String.Set.of_list words in
String.Set.length set = List.length words

let sort_chars word =
String.to_list word
|> List.sort ~cmp:Char.compare
|> String.of_char_list

let sort_words words =
List.map words ~f:sort_chars

let no_anagrams = Fn.compose all_unique_words sort_words

let solve () =
let split_words = String.split ~on:' ' in
let passphrases = In_channel.read_lines "./2017/data/4.txt" |> List.map ~f:split_words in

List.filter passphrases ~f:all_unique_words
|> List.length
|> printf "a: %d\n";

List.filter passphrases ~f:no_anagrams
|> List.length
|> printf "b: %d\n";


 No.832225>>832228

File (hide): a94d3fcb1707cc7⋯.png (40.63 KB, 986x294, 493:147, day4.png) (h) (u)

Mathematica makes short work of it.


 No.832228

>>832225

It can even be golfed shorter, this guy on reddit did it even nicer, hiding my explicit 'True'.

https://www.reddit.com/r/adventofcode/comments/7hf5xb/2017_day_4_solutions/dqqjj88/


 No.832234

>>832222

oh yeah, it's the point-less style


 No.832236

>>832221

fug, of course it's somethingML.

they look very similar when I haven't written in neither of them for a year.


 No.832272>>832274 >>832906

I'm the semicolon python fag, got this for day 3:


import sys;
n = int(sys.stdin.readline()) - 1;
diag = int(n ** 0.5);
walk = n - diag * diag;
disc = walk % (diag + diag % 2);
offset = diag // 2 - abs(disc - diag // 2);
print(diag - offset);


 No.832274>>832275

>>832272

explain yourself

trying to smudge your code fingerprint so that you won't get outed as Google Drone #171234 ?


 No.832275

>>832274

You mean the semicolons? I'm used to C like languages that's all. I'm doing these in python because I already know C pretty well.


 No.832293>>832300 >>832420

fn main() {
let instant = std::time::Instant::now();

let (a, b) = INPUT
.lines()
.filter_map(|l| {
let mut set = FastHashSet::default();
if l.split(' ').all(|s| set.insert(s)) {
Some(set)
} else {
None
}
})
.fold((0, 0), |(a, b), s| {
let mut set = FastHashSet::default();
let valid = s.iter()
.map(|s| {
let mut v = s.as_bytes().to_owned();
v.sort_unstable();
v
})
.all(|b| set.insert(b));
(a + 1, if valid { b + 1 } else { b })
});

let d = instant.elapsed();
println!(
"Part 1: {}\nPart 2: {}\nTime: {} ms",
a,
b,
(d.as_secs() as f64 + d.subsec_nanos() as f64 / 1000000000.0) * 1000.0
);
}

https://play.rust-lang.org/?gist=6380b10c0b0ec10a0b742507b050ca92

Time: 0.52 ms


 No.832300>>832319

>>832293

that's some tolerable-looking rust you got right there. eyes aren't bleeding at all. Even so:

>std::time::Instant::now();

not really an improvement over the time() as used by the Greeks and Romans in antiquity

>FastHashSet::default()

if it's the 'default', why do you have to say that?

>INPUT

eyes status: getting a little bit bloodshot

> (d.as_secs() as f64 + d.subsec_nanos() as f64 / 1000000000.0) * 1000.0

well ha ha who would expect an answer in fractional msecs? that must be super rare and not the most obviously desirable benchmarking number, next to fractional seconds

still, not bad. would work with rather than ritually commit seppuku.


 No.832301>>832304

>>832221

the virgin haskeller

>thinks functional languages are important

>reads academic programming papers in his spare time just to understand how to write hello world

>purchased a graph theory textbook

>knows what a monad is

>solves programming puzzles for fun

>gives all his variables a type even though the compiler does it automatically

>programs "for the sake of the craft"

THE CHADSNAKE

>writes everything in python because it's the easiest

>thinks "programming paradigms" are for loser nerds

>has never spawned a thread in his life

>takes all his algorithms unashamedly from stack overflow

>first program was an automated trading script, written in half a day, exponential gains everyday

>will never write a line of code for free or for fun

>goes to sleep without thinking about computers


 No.832304

File (hide): c5f242d45e6ded2⋯.jpg (112.89 KB, 800x559, 800:559, alone.jpg) (h) (u)

>>832301

That's hilarious.


 No.832319

>>832300

Thanks for the code review.


 No.832368

>>832222

>nub

O(n^2)


 No.832369

d4p1


(import (srfi srfi-1) (ice-9 rdelim))

(define (valid? str)
(let ((lst (sort (string-split str char-set:blank) string<?)))
(not (any string=? lst (cdr lst)))))

(let loop ((line (read-line)) (count 0))
(if (eof-object? line)
(display count)
(loop (read-line) (+ count (if (valid? line) 1 0)))))

d4p2


(import (srfi srfi-1) (ice-9 rdelim))

(define (sort-string str)
(list->string (sort (string->list str) char<?)))

(define (valid? str)
(let ((lst (sort (map sort-string (string-split str char-set:blank)) string<?)))
(not (or (string-null? str) (any string=? lst (cdr lst))))))

(let loop ((line (read-line)) (count 0))
(if (eof-object? line)
(display count)
(loop (read-line) (+ count (if (valid? line) 1 0)))))


 No.832420>>832429 >>832472

File (hide): acb674ddae65ec3⋯.png (152.28 KB, 978x2540, 489:1270, Screen Shot 2017-12-04 at ….png) (h) (u)

File (hide): 275286846288e05⋯.jpg (119.92 KB, 1024x683, 1024:683, steve klabnik 3.jpg) (h) (u)

>>832293

I optimized it: https://play.rust-lang.org/?gist=e036c920b0c5bc7bfec445cabf2473f9

Time: 0.3 ms

Suck it faggots! Rust is literally the fastest and safest language.


 No.832429>>832432

>>832420

>hash with no collision strategy

>fixed max size of 32

>assert that it's fine and then turn the assertions off for 'speed'

just use Forth. it compiles a lot faster.


 No.832432>>832436

>>832429

>hash with no collision strategy

It uses linear probing though


 No.832436

>>832432

oh. yeah I see it now.


 No.832472>>832473 >>832478 >>832540 >>832554

>>832420

fuuuuuuuuuuuuuark

module HashSet =
struct
let hashset_capacity = 32

type 'a hashset = {
buckets : (int * 'a) array;
hash_fn : 'a -> int;
mutable len : int;
}

let create f x =
{ buckets = Array.make hashset_capacity (0, x);
hash_fn = f;
len = 0 }

(* unlike rust, infinite loop possible in loop if hash state goes bad *)
let insert ht v =
assert (ht.len < hashset_capacity);
let hash = ht.hash_fn v in
let index = hash mod hashset_capacity in
let rec loop i =
let i' = (index + i) mod hashset_capacity in
match ht.buckets.(i') with
| (0, _) ->
ht.buckets.(i') <- (hash, v);
ht.len <- ht.len + 1;
true
| (h', v') when h' = hash && v' = v -> false
| (h', v') when h' = hash ->
(* of course this happens if we hash sorted strings
but store the original string... you know what?
let's just pretend legit collisions never happen *)
false
| _ -> loop (i + 1)
in loop 0

let clear ht x =
Array.fill ht.buckets 0 (Array.length ht.buckets) (0, x);
ht.len <- 0
end

let hash_asis = Hashtbl.hash

let hash_sorted s =
let a = Array.make (String.length s) ' ' in
for i = 0 to (String.length s - 1) do
a.(i) <- s.[i]
done;
Array.fast_sort (fun a b -> if a = b then 0 else if a > b then 1 else -1) a;
Hashtbl.hash a

let () =
let before = Unix.gettimeofday () in
let asis = HashSet.create hash_asis "" in
let sorted = HashSet.create hash_sorted "" in
let count_asis = ref 0 in
let count_sorted = ref 0 in
let rec check_asis words =
match words with
| w :: words' -> if HashSet.insert asis w then check_asis words'
| [] -> count_asis := !count_asis + 1 in
let rec check_sorted words =
match words with
| w :: words' -> if HashSet.insert sorted w then check_sorted words'
| [] -> count_sorted := !count_sorted + 1 in
let rec loop list =
match list with
| [] ->
let after = Unix.gettimeofday () in
Printf.printf "Part 1: %d\nPart 2: %d\nTime: %f s\n"
!count_asis !count_sorted (after -. before)
| phrase :: rest ->
HashSet.clear asis "";
HashSet.clear sorted "";
let words = String.split_on_char ' ' phrase in
check_asis words;
check_sorted words;
loop rest
in loop passphrases
built and used as:
$ ocamlopt -O3 unix.cmxa riio.ml -o riio
$ ./riio
Part 1: 337
Part 2: 231
Time: 0.003408 s

why is it not faster orz

(changed on hash functions because I don't understand them)

(no hash collision because I didn't want to rewrite code to store sorted value after I realized the mistake)


 No.832473>>832522

File (hide): 0aa1ff2db4a713b⋯.png (98.42 KB, 682x759, 62:69, hashset-goldenrod.png) (h) (u)

>>832472

>that syntax highlighting

no serious language uses ' for strings


 No.832478

>>832472

>why is it not faster orz

Because Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.


 No.832522>>832541

>>832473

>those comments

allaha huakbar


 No.832540>>832544


 No.832541

>>832522

#2: I know collisions don't happen and it's a pretty bullshit data structure anyway :)

#1: the infinite loop requires a bug, for it actually happen. I'm just pointing out a subtle difference in implementation, since I'm mirroring the rust code and that part is different. (it's different because I don't actually know if OCaml has a way to escape early from iterative loops).

>arab mating call

pajeets speak 'english'.


 No.832544>>832546

>>832540

>citing the shootout

>in CY+2

on this real world toy problem OCaml and Rust both take no time. That's fine with me.


 No.832546>>832550 >>832891

>>832544

actually yours takes more than 1 ms which means you have failed. read the aoc lore. you only have 1 ms for each challenge.


 No.832550>>832554

>>832546

it takes more than 1ms on my laptop. my laptop can't digitize people.

you know I didn't actually compare rust against ocaml directly? That would require I install rust. I only have 1TB & 256G disks in this thing.


 No.832554

>>832550

>my laptop can't digitize people.

irrelevant

>I didn't actually compare rust against ocaml directly?

wrong: >>832472 > fuuuuuuuuuuuuuark>why is it not faster orz

>I only have 1TB & 256G disks in this thing.

I don't understand.

>du -h .rustup/toolchains/stable-x86_64-unknown-linux-gnu/

>588M

where is the problem?


 No.832839>>832850 >>832889

can someone help me with my math for the day 3 part one... abstracted it down to about this then got stuck chasing bugs.. again in pony

fun dist_square(stop': USize) :USize =>
let stop = (consume stop').isize()
var len = ISize(1)
// i don't have square root.. or powers..
while (len * len) < stop do
len = len + 2
end

let dif = (len * len) - stop
var corner = dif % (len-1)
corner = len - if corner < ((len-1)/2) then
corner
else
(corner - (len-1)).abs().isize()
end
// my output
((len -1)- corner).usize()


 No.832840>>832876

Not one person has submitted a prolog solution. Aren't there any men around here?


 No.832850>>832871 >>832873 >>832889

>>832839

What are you trying to do here?


 No.832871>>832873 >>832889

>>832850

in the problem the last number per layer will always be an odd number squared

17  16  15  14  13
18 5 4 3 12
19 6 1 2 11
20 7 8 9 10
21 22 23 24 25

the while loop finds the first odd number that when squared is more then the input number.

that number is the length of one side.

the next line calculates how far back from the end of the layer the input is.

corner starts as how far from the corner closest to the end of the layer the number is, but then should be converted to how far from a corner it is.

then the output (last line) should be the length of one side (max length away from the center for that layer) - how far from the corner the number is..

this works for the first few but falls apart somewhere. all of this is using signed integers so subtraction shouldn't cause overflows.. i'm just stuck.. probably been looking at this too long

ended up diagramming the math and still cant figure it out.


 No.832873>>832889

>>832871

>>832850

i guess i should say shell not layer


 No.832876>>832887

>>832840

passphrase.m

:- module passphrase.
:- interface.
:- import_module list, string.
:- type strictness ---> norepeats; no_anagrams.
:- pred is_valid(strictness::in, list(string)::in) is semidet.
:- implementation.
:- use_module set.

is_valid(S, L) :-
is_valid(S, L, set.init).

:- pred is_valid(strictness::in, list(string)::in, set.set(string)::in) is semidet.
is_valid(_, [], _).

is_valid(norepeats, [H|T], S) :-
not set.contains(S, H),
is_valid(norepeats, T, set.insert(S, H)).

is_valid(no_anagrams, [H|T], S) :-
H1 = from_char_list(sort(to_char_list(H))),
not set.contains(S, H1),
is_valid(no_anagrams, T, set.insert(S, H1)).
puzzle.m
:- module puzzle.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module string, list, int, passphrase, time.

main(!IO) :-
time(Start, !IO),
read_file_as_string(Res, !IO),
(
Res = ok(Input),
Phrases = map(split_at_char(' '), filter(notempty, split_at_char('\n', Input))),
count(Phrases, A, B),
io.format("part 1: %d\npart 2: %d\n", [i(A), i(B)], !IO),
time(End, !IO),
io.format("Time: %f s\n", [f(difftime(Start, End))], !IO)

;
Res = error(_, Err),
io.format("this happened: %s :(\n", [s(error_message(Err))], !IO)
).

:- pred notempty(string::in) is semidet.
notempty(S) :- length(S) > 1.

:- pred count(list(list(string))::in, int::out, int::out) is det.
count(L, A, B) :- count(L, 0, A, 0, B).

:- pred count(list(list(string)), int, int, int, int).
:- mode count(in, in, out, in, out) is det.
count([], !A, !B).
count([H|T], !A, !B) :-
( passphrase.is_valid(norepeats, H) -> !:A = !.A + 1 ; !:A = !.A ),
( passphrase.is_valid(no_anagrams, H) -> !:B = !.B + 1 ; !:B = !.B ),
count(T, !A, !B).
usage:
$ ./puzzle < ../day-3.txt 
part 1: 337
part 2: 231
Time: 0.000000 s


 No.832887>>832888

>>832876

Very noice.


 No.832888

>>832887

check em'


 No.832889>>832906

>>832873

>>832871

>>832850

>>832839

figured part one of day three out.. removed my conditional.. it's "all" math now.

fun dist_square(input': USize) :USize =>
let input = (consume input').isize()
var len = ISize(1)
// i don't have square root.. or powers..
while (len * len) < input do
len = len + 2
end
/* if i could i would:
len = floor(sqrt(input))
len = (len % 2) + len + 1 */

let dif = (len * len) - input
let corner = ((dif % (len-1)) - ((len-1)/2)).abs().isize() + ((len-1)/2)
Debug(input.string() + " " + corner.string())


 No.832890>>833433

day 5. it just werks

auto by_line = [](char c) { return c != '\n'; };
auto to_int = [](string_view sv) { return stoi(string(sv)); };
void twisty_trampolines1(string input)
{
vector<int> jumps;
for (int jump : input | split(by_line) | map_to(to_int))
jumps.push_back(jump);
size_t njumps = 0;
for (size_t i = 0, sz = jumps.size(); i < sz; ++njumps)
i += jumps[i]++;
cout << njumps;
}
void twisty_trampolines2(string input)
{
vector<int> jumps;
for (int jump : input | split(by_line) | map_to(to_int))
jumps.push_back(jump);
size_t njumps = 0;
for (size_t i = 0, sz = jumps.size(); i < sz; ++njumps){
int jump = jumps[i];
if (jump >= 3) --jumps[i]; else ++jumps[i];
i += jump;
}
cout << njumps;
}


 No.832891>>832893

>>832546

>you only have 1 ms for each challenge

really?

how would they check that?


 No.832893>>832913

>>832891

They don't? The theme this year was that you get sucked into a computer at 50ms before Christmas, and if you don't finish helping the computer in 50 ms Christmas is ruined. Each of the 50 tasks takes 1ms and there's 2 each day for 25 days. It's not real.


 No.832894>>832904

fucking hell, I was stumped for a good five minutes because I kept interpreting "three or more" as "> 3". I kept looking for alternative interpretations of "offset" instead.

let inst_count = ref 0

let eval start a =
inst_count := 0;
let len = Array.length a in
let rec loop i =
inst_count := !inst_count + 1;
let n = a.(i) in
let i' = i + n in
if i' < 0 || i' >= len then () else
begin
(* a.(i) <- n + 1; *)
a.(i) <- n + (if n >= 3 then -1 else 1);
loop i'
end
in loop start

let assemble s =
let rec pop sign num i at start acc =
if i = String.length(s) then (start, sign * num :: acc) else
match s.[i] with
| '-' -> pop (-1) num (i + 1) at start acc
| ')' -> loop (i + 1) (at + 1) start (sign * num :: acc)
| ' ' -> loop (i + 1) (at + 1) start (sign * num :: acc)
| c when c >= '0' && c <= '9' ->
pop sign (num * 10 + int_of_char(c) - int_of_char('0')) (i + 1) at start acc
| _ -> failwith "invalid character in instruction string"
and loop i at start acc =
match s.[i] with
| '(' -> loop (i + 1) at at acc
| ' ' -> loop (i + 1) at start acc
| ')' -> loop (i + 1) at start acc
| _ -> pop 1 0 i at start acc
in
let start, list = loop 0 0 0 [] in
(start, Array.of_list(List.rev(list)))

let steps s =
let start, a = assemble s in
eval start a;
!inst_count
also totally pointless 'find out where we're to start' code, looking for parenthesized numbers in input.


 No.832904

>>832894

pretty sure pesonal stats weren't there before?

      --------Part 1--------   --------Part 2--------
Day Time Rank Score Time Rank Score
5 00:33:39 1770 0 00:42:03 1733 0
4 00:35:17 1604 0 00:44:28 1445 0
3 02:13:31 1684 0 02:27:53 1105 0
2 04:38:52 4456 0 04:53:07 3803 0
1 22:16:01 18144 0 22:22:10 15086 0

so nearly 10 minutes due to >= not being >

it was such a minor code change too


 No.832906

>>832889

I've already done it here:

>>832272


 No.832913

>>832893

Actually it is 25 ms before christmas. You have 1ms for both path parts.


 No.832955>>832961 >>833615

fn main() {
let instant = std::time::Instant::now();

let ops: Vec<i32> = INPUT.lines().map(|l| l.parse().unwrap()).collect();

let a = execute(&mut ops.clone(), |v| v + 1);
let b = execute(&mut ops.clone(), |v| if v >= 3 { v - 1 } else { v + 1 });

let d = instant.elapsed();
println!(
"Part 1: {}\nPart 2: {}\nTime: {} ms",
a,
b,
(d.as_secs() as f64 + d.subsec_nanos() as f64 / 1000000000.0) * 1000.0
);
}

fn execute(ops: &mut [i32], f: fn(i32) -> i32) -> u32 {
let mut steps = 0;
let mut i = 0;

while (i as usize) < ops.len() {
let o = &mut ops[i as usize];
i += *o;
*o = f(*o);
steps += 1;
}

steps
}

https://play.rust-lang.org/?gist=c48827dcbf01fb0efa5acbfe7442303e

Time: 83 ms

I fucking blew it. I ruined Christmas.


 No.832961

>>832955

I guess all that safety comes at a price :^)


 No.832962>>832965

File (hide): 95f8e1e5087f8e8⋯.png (174.8 KB, 1214x1262, 607:631, day5.png) (h) (u)

Mathematica.

Part1 was straight forward. Side effect heavy loops like my part 2 solution, which spend a lot of time in the language rather than library functions is the bane of performance. After 45 seconds I still didn't have an answer for part2!!! The remedy is to use compiled functions, where simpler code is emitted which makes use of some type assumptions, that yielded a result in 2 seconds. Even more gains can realized by emitting C code. That got it down to 0.5 secs, won't win a speed record, but it'll do. Thanks C!


 No.832965

File (hide): 7c673f793dcb686⋯.png (10.54 KB, 211x246, 211:246, 7c6.png) (h) (u)

>>832962

>After 45 seconds I still didn't have an answer for part2

damn


 No.832982>>832987 >>833317

File (hide): bf8344dd75159b7⋯.png (29.33 KB, 386x266, 193:133, stats.png) (h) (u)

Pretty substantial drop off from day 2 to 3.


 No.832987>>833035

File (hide): af805b975120e32⋯.mp4 (353.03 KB, 320x240, 4:3, iambecomedeath.mp4) (h) (u) [play once] [loop]

>>832982

Can you hear that? It's the sound of over 9000 Pajeets vanishing.


 No.833035>>833317

>>832987

day 5 was pretty easy. not a shock like day 3 was. it's probably just Monday night and people having jobs.


 No.833102>>833105 >>833115

Day 5 in Rust: https://play.rust-lang.org/?gist=7b0b5ddc9fa74443e2257f80108d63df&version=stable

use std::fs::File;
use std::io::{BufReader, BufRead};

fn part1(mut jumps: Vec<i32>) -> u32 {
let len = jumps.len();
let mut i = 0;
let mut ctr = 0;

while i < len {
jumps[i] += 1;
i = (i as i32 + jumps[i] - 1) as usize;
ctr += 1;
}

ctr
}

fn part2(mut jumps: Vec<i32>) -> u32 {
let len = jumps.len();
let mut i = 0;
let mut ctr = 0;

while i < len {
if jumps[i] >= 3 {
jumps[i] -= 1;
i = (i as i32 + jumps[i] + 1) as usize;
} else {
jumps[i] += 1;
i = (i as i32 + jumps[i] - 1) as usize;
}
ctr += 1;
}

ctr
}

fn main() {
let file = File::open("input").unwrap();
let mut jumps: Vec<i32> = vec![];
for line in BufReader::new(file).lines() {
jumps.push(line.unwrap().parse::<i32>().unwrap());
}

println!("{}", part1(jumps.clone()));
println!("{}", part2(jumps.clone()));
}

Takes about 3 seconds.


 No.833105

>>833102

Forgot to use --release, now it runs in about 100ms.


 No.833115>>833118 >>833193

>>833102

Not awful but still pretty bad.

>File::open("input")

read from stdin and pipe input into it

>manually collecting into a collection

use Iterator::collect

>parse::<i32>()

you already have said that you want i32. no need to use the ugly turbofish syntax.

>part1 and part2

there is only a minor difference between those. also there is no need to give thos functions a vec. just give them a &mut [i32].

>doing bounds checking multiple times

maybe the compiler is smart enough to remove them, but check out slice::get_mut

Take a look at this:

use std::io::BufRead;

fn main() {
let stdin = std::io::stdin();
let ops: Vec<i32> = stdin
.lock()
.lines()
.map(|l| l.unwrap().parse().unwrap())
.collect();

let a = execute(&mut ops.clone(), |v| v + 1);
let b = execute(&mut ops.clone(), |v| if v >= 3 { v - 1 } else { v + 1 });

println!("{} {}", a, b);
}

fn execute(ops: &mut [i32], f: fn(i32) -> i32) -> u32 {
let mut steps = 0;
let mut i = 0;

while let Some(o) = ops.get_mut(i as usize) {
i += *o;
*o = f(*o);
steps += 1;
}

steps
}


 No.833118>>833119

>>833115

Thank you for your feedback. I've seen your post but only after I posted my solution.

>also there is no need to give thos functions a vec. just give them a &mut [i32].

We both call .clone() on a Vec<i32>, which returns a Vec<i32> but gets casted (?) to a &mut [i32] without actually changing any data. Or is there any difference?


 No.833119

>>833118

No there really isn't a difference. I was just nitpicking.


 No.833124

Scrub tier perl solutions for day5


use strict;
use warnings "all";

my @data;
while (<DATA>) {
push(@data, $_);
}

my $size = int @data;
my $index = 0;
my $jumps = 0;
for (;;) {
$index += $data[$index]++;
++$jumps;
if ($index > $#data) {
die "$jumps\n";
}
}

__DATA__
0
3
0
1
-3


use strict;
use warnings "all";

my @data;
while (<DATA>) {
push(@data, $_);
}

my $size = int @data;
my $index = 0;
my $jumps = 0;
for (;;) {
$index += $data[$index] >= 3 ? $data[$index]-- : $data[$index]++;
++$jumps;
if ($index > $#data) {
die "$jumps\n";
}
}

__DATA__
0
3
0
1
-3


 No.833131>>833188

Ungolfed Perl6:


my $i = 0;
my $res= 0;
my $instr = lines.map(+*).Array;

while ($i < $instr.elems) {
$i += $instr[$i] >= 3 ?? $instr[$i]-- !! $instr[$i]++;
$res++;
}

$res.say


~ $ time perl6 dik.pl6 < input
23948711

real 1m40.691s
user 1m40.647s
sys 0m0.037s

Compared to my Rust version thats pretty much the one Steve Klabnik posted:


~ $ time ./dik < input
23948711

real 0m0.054s
user 0m0.051s
sys 0m0.003s

Perl6 truly is the future of computing.


 No.833160


push@_,$_ while<>;$i+=$_[$i]>=3?$_[$i]--:$_[$i]++while$i<~~@_&&++$a;print$a.$/


~ $ time perl dik.pl < input
23948711

real 3.35s
user 3.34s
sys 0.00s


 No.833188

>>833131

rip perl6, we hardly knew ya


 No.833190>>833193

>all these implementations that only check for i < arraysize

fug did I imagine that requirement as well?

<The goal is to follow the jumps until one leads outside the list.

nope, that's pretty clear. i < 0 is also outside the array. this contest just doesn't demand much of what it says it does.


 No.833193

>>833190

In my solution >>833115 i is a signed integer that I cast to an unsigned one. Thanks to the awesomness of two's complement this just werks.


 No.833262>>833266 >>833300 >>833334

Did almost all of them in python but stuck on puzzle 3. Any hints? pls no spoilers


 No.833266>>833334

>>833262

You either generate the spiral and keep track of two coordinates, or you just work it out with math.


 No.833300

>>833262

an easy way to do the spiral in python would be to use 2d coordinates as dictionary keys


 No.833317

>>833035

>>832982

school... it's finals season so (I) can't code much.

as soon as school is done it's all i'll be doing though.


 No.833326

File (hide): 3230acf475b4d5e⋯.png (157.09 KB, 388x1238, 194:619, 2016.png) (h) (u)

2016 stats. The dropoff was gradual, but pretty substantial from day 1 to 25. Looks like there's a lot more people doing it this year. I did 2015 at the time, but I'm going back and doing the 2016 ones now as well.


 No.833334>>833390

>>833262

>>833266

You could also do recursion, like one of the R*st solutions in this thread. Hint: don't.


 No.833390>>833394

>>833334

Kinda unrelated but, I'm thinking of doing a libparseinput (get_next_word, get_next_number etc) and them doing every challenge in C, then release it on github as a portfolio sort of thing. Is this a good idea or should I not bother?


 No.833394

>>833390

It's certainly not a bad idea, but keep in mind that there are already thousands out there, so make sure it represents your best work.


 No.833431

d5


(define* (read-input #:optional (acc '()))
(let ((elem (read)))
(if (eof-object? elem)
(reverse acc)
(read-input (cons elem acc)))))

(define* (count-jumps array #:optional (part 1) (idx 0) (count 1))
(let* ((value (array-ref array idx))
(new-idx (+ idx value))
(inc (if (and (= part 2) (>= value 3)) 1- 1+)))
(if (array-in-bounds? array new-idx)
(begin (array-set! array (inc value) idx)
(count-jumps array part new-idx (1+ count)))
count)))

(let ((input (read-input)))
(format #t
"~A\n~A\n"
(count-jumps (list->array 1 input) 1)
(count-jumps (list->array 1 input) 2)))


 No.833433>>833435 >>833439

>>832890

What language is this?


 No.833435

And done for day 6.

bool by_word(char c) { return !isspace(c); }
void memory_reallocation1(string input)
{
string mem;
for (int val : input | split(by_word) | map_to(to_int))
mem.push_back(val);
unordered_set<string> seen;
size_t ncycles = 0;
for (; !seen.count(mem); ++ncycles){
seen.insert(mem);
auto it = max_element(mem.begin(), mem.end());
int redist = *it;
*it = 0;
for (size_t sz = mem.size(), i = (it - mem.begin() + 1) % sz; redist; ++i %= sz){
++mem[i];
--redist;
}
}
cout << ncycles;
}
void memory_reallocation2(string input)
{
string mem;
for (int val : input | split(by_word) | map_to(to_int))
mem.push_back(val);
unordered_map<string, size_t> seen;
size_t ncycles = 0;
for (; !seen.count(mem); ++ncycles){
seen.emplace(mem, ncycles);
auto it = max_element(mem.begin(), mem.end());
int redist = *it;
*it = 0;
for (size_t sz = mem.size(), i = (it - mem.begin() + 1) % sz; redist; ++i %= sz){
++mem[i];
--redist;
}
}
cout << ncycles - seen[mem];
}

>>833433

Just good old C++.


 No.833439

>>833433

are you retarded


 No.833450>>833451

wtf does part 2 of day 6 even mean?


 No.833451>>833452 >>833453

>>833450

god fucking damnit it's asking the same exact question again and expecting a different answer.


 No.833452

>>833451

close, but not exactly


 No.833453

>>833451

ugh ok. 2nd question says "you see X again after 4 cycles so the answer is 4". 4 is also the answer when you put X itself into your block-reallocation function, but what they mean is "given the input from the first example the repeat that ends the sequence is seen again 4 cycles after the first time it was seen"


 No.833454>>833500

let smooth_from a i =
let len = Array.length a in
let blocks = a.(i) in
let to_each = int_of_float (floor (0.5 +. (float blocks /. float len))) in
a.(i) <- 0;
let rec loop j rest =
a.(j) <- a.(j) + (max 0 (min to_each rest));
if rest < 0 || i = j then () else
loop ((j + 1) mod len) (rest - to_each)
in loop ((i + 1) mod len) blocks

let max_block a =
let max, maxi = ref a.(0), ref 0 in
for i = 1 to Array.length a - 1 do
if a.(i) > !max then (max := a.(i); maxi := i)
done; !maxi

let smooth a =
let seen = Hashtbl.create (Array.length a) in
let wtf a = String.concat ":" (Array.fold_left (fun acc n -> string_of_int n :: acc) [] a) in
let steps = ref 0 in
while None = (Hashtbl.find_opt seen (wtf a)) do
Hashtbl.add seen (wtf a) !steps;
smooth_from a (max_block a);
steps := !steps + 1
done;
(!steps, !steps - Hashtbl.find seen (wtf a), a)
1. the 'wtf' function is of course a wtf; I should have a real hash function for the array and use that instead.

2. the max block should probably be tracked while reallocating, so that it doesn't have to be looked up again

3. with the input as small as they are one option would be to use Bytes (a mutable string) instead of an array of ints. that gets rid of the wtf function


 No.833467>>833529

d6


(define (redist! lst)
(define (circ-cdr lst cur)
(if (pair? (cdr cur)) (cdr cur) lst))
(let* ((max-blocks (apply max lst))
(max-pair (memq max-blocks lst)))
(set-car! max-pair 0)
(let loop ((current-pair (circ-cdr lst max-pair)) (blocks-left max-blocks))
(if (> blocks-left 0)
(begin
(set-car! current-pair (1+ (car current-pair)))
(loop (circ-cdr lst current-pair) (1- blocks-left)))))))

(define* (read-input #:optional (acc '()))
(let ((elem (read)))
(if (eof-object? elem)
(reverse acc)
(read-input (cons elem acc)))))

(let loop ((lst (read-input)) (htable (make-hash-table)) (count 1))
(hash-set! htable (list-copy lst) count)
(redist! lst)
(let ((value (hash-ref htable lst)))
(if value
(format #t "~A\n~A\n" count (- count value -1))
(loop lst htable (1+ count)))))


 No.833471>>833775

File (hide): 80dd2766b0bc306⋯.png (144.12 KB, 990x868, 495:434, day6.png) (h) (u)

Day 6 (cleaned up a bit)


 No.833473>>833475

What happens if day 6 part 1's input is [2, 0, 0, 0]? To evenly distribute 2 over 3 fields, each must get 0, so the first field gets 2 back. Right?


 No.833475

>>833473

nevermind, I misunderstood the question


 No.833491>>833492

Day 6 in Rust: https://play.rust-lang.org/?gist=6cdb06cdd8dfa521045f5054d1cf2223&version=stable

const NUM_MEMBANKS: usize = 4;

fn main() {
let input = [0, 2, 7, 0];

let mut ctr = 0;
let mut history = vec![input];
let size;

loop {
ctr += 1;
let largest = history.last().unwrap().iter().enumerate().fold(
(0, 0),
|acc, x| {
if *x.1 > acc.1 {
(x.0, *x.1)
} else {
acc
}
}
);

let mut i = (largest.0 + 1)%NUM_MEMBANKS;
let mut new = *history.last().unwrap();
new[largest.0] = 0;
for _ in 0..largest.1 {
new[i] += 1;
i = (i + 1)%NUM_MEMBANKS;
}

if history.contains(&new) {
size = history.iter().position(|&x| x == new).unwrap();
break;
} else {
history.push(new);
}
}

println!("Part 1: {}", ctr);
println!("Part 2: {}", ctr-size);
}

So today I learned Rust has no sizeof().


 No.833492>>833495 >>833496


 No.833495>>833496

>>833492

You're right. While I was writing my solution I had a different approach in mind where I had to pass the input array to a function. I could have either passed a reference, which wasn't what I wanted, or I could have specified the array's size in the function declaration, where .len() doesn't work.


 No.833496

>>833492

>>833495

Like this:

const arr: [u32; 3] = [1,2,3];

fn test(x: [u32; arr.len()]) {
println!("{:?}", x);
}

fn main() {
test(arr);
}


 No.833500

>>833454

less wtf:

let max_block b =
let max, maxi = ref (Bytes.unsafe_get b 0), ref 0 in
Bytes.iteri (fun i c -> if c > !max then (max := c; maxi := i)) b;
!maxi

let balance2 b =
let hash x = Hashtbl.hash x in
let len = Bytes.length b in
let seen = Hashtbl.create len in
let get i = int_of_char (Bytes.unsafe_get b i) in
let set i n = Bytes.unsafe_set b i (char_of_int n) in
let reallocate i =
let blocks = get i in
let to_each = int_of_float (floor (0.5 +. (float blocks /. float len))) in
set i 0;
let rec loop j rest =
set j (get j + (max 0 (min to_each rest)));
if rest < 0 || i = j then () else
loop ((j + 1) mod len) (rest - to_each)
in loop ((i + 1) mod len) blocks
in let rec loop = function
| None ->
Hashtbl.add seen (hash b) (Hashtbl.length seen);
reallocate (max_block b);
loop (Hashtbl.find_opt seen (hash b))
| Some last ->
(Hashtbl.length seen, Hashtbl.length seen - last)
in loop None


 No.833502

rare instance found of actually readable Haskell

naturally the author posted it with a sincere apology. that community is fucked

import Data.Sequence (Seq)
import qualified Data.Sequence as Seq

import Data.Set (Set)
import qualified Data.Set as Set

import Data.List

distribute :: Int -> Int -> Seq Int -> Seq Int
distribute 0 _ banks = banks
distribute remaining currentIndex banks = distribute newRemaining newIndex newBanks
where newRemaining = remaining - 1
newIndex = mod (currentIndex + 1) (length banks)
newBanks = Seq.adjust (+1) currentIndex banks

doCycle :: Seq Int -> Seq Int
doCycle banks = distribute largestBank startIndex withoutLargest
where largestBank = maximum banks
bankIndex = head $ Seq.elemIndicesL largestBank banks
startIndex = mod (bankIndex + 1) (length banks)
withoutLargest = Seq.update bankIndex 0 banks

getFirstRepeatedConfig :: Int -> Seq Int -> Set (Seq Int) -> (Int, Seq Int)
getFirstRepeatedConfig count banks prevConfigs
| Set.member banks prevConfigs = (count, banks)
| otherwise = getFirstRepeatedConfig newCount newBanks newPrevConfigs
where newCount = count + 1
newBanks = doCycle banks
newPrevConfigs = Set.insert banks prevConfigs

getTimeToCycle :: Int -> Seq Int -> Seq Int -> Int
getTimeToCycle count banks targetConfig
| banks == targetConfig = count
| otherwise = getTimeToCycle newCount newBanks targetConfig
where newCount = count + 1
newBanks = doCycle banks

main :: IO ()
main = do
contents <- readFile "../input.txt"
let banks = Seq.fromList $ map read $ words contents
let (cycleTime, banksAfter) = getFirstRepeatedConfig 0 banks Set.empty
let timeToNextCycle = getTimeToCycle 1 (doCycle banksAfter) (banksAfter)
putStrLn $ "Solution 1:" ++ (show cycleTime)
putStrLn $ "Solution 2:" ++ (show timeToNextCycle)


 No.833529

>>833467

(((functional programming)))


 No.833532

File (hide): 59c9a0661723e4a⋯.jpeg (37.72 KB, 390x512, 195:256, 1458070789710.jpeg) (h) (u)

perl is perlfect for challenges because it lets you do anything even if its retarded beyond belief


 No.833534>>833536 >>833544 >>833547

How the FUCK are you supposed to do days 5 and 6 in under 1ms?????????????????

What the FUUUCK. I just can't get day 6 below 1.2ms.


 No.833536>>833537

>>833534

You don't need to????


 No.833537>>833538

>>833536

I want to!


 No.833538>>833539

>>833537

Take your autism and leave


 No.833539


 No.833544>>833546

>>833534

How did you do day 6 in 1.2ms?

I'd store already visited values in a stack allocated binary tree and use SIMD instructions for adding the numbers. I'll try that later when I'm home again and if I'm not too drunk.


 No.833546>>833743 >>833942

>>833544

>binary tree

too slow

>SIMD

llvm already does that for me


 No.833547

>>833534

Treat the puzzle input as the real world application that you're optimizing for. Look for useful properties.

1. Small array: 16 elements

Small numbers: each fits in a nibble (4 bits, one hexadecimal digit)

4 * 16 = 64 bits. sound familiar?

2. if each number you look at fits in 4 bits, you will always do one of at most 16 possible things to the rest of the array. Depending also on the index of the number you're looking at, so 16*16=256 possible things based on index and number at that index.

3. Maybe there are useful patterns within the 256 total manipulations.


 No.833551>>833558


 No.833558>>833604

>>833551

Hmm if I run it 1000 times and take the average time it is <1ms. I'll take. Christmas is saved!!!

https://play.rust-lang.org/?gist=a20ae380e856126347b419f65743373f&version=nightly&mode=release

Time: 0.9 ms


 No.833604>>833615

>>833558

You've got 25 ms total though, so as long as your averaging under 1ms you'll be fine. You should link all your solutions together and see if it they collectively run under 25 (6 for now) ms.


 No.833615>>833624

>>833604

Every day except 5 runs under 1ms. Day 5 takes 83 ms: >>832955

>You should link all your solutions together

I'm doing that. Right now it is a mess though. Once I've cleaned it up I'll make a ShitHub repo.


 No.833624

>>833615

Ahh, day 5 is going to make it rather untenable then. And who knows what length solutions lie ahead.


 No.833633>>833639 >>834115

/**
* Copyright m712 2017.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

struct pos {
int item, index;
};

void
print_banks(int *banks, int blen) {
printf("[");
for (int i = 0; i < blen; i++)
printf("%d, ", banks[i]);
printf("\b\b] \n");
}

int
next_int() {
int val = 0;
char c;
while (isdigit((c = getchar()))) {
val *= 10;
val += c - '0';
}

if ((int) c == EOF) return EOF;
else if (!isspace(c)) {
fprintf(stderr, "Not a number");
abort();
}

return val;
}

void
push_to_banks(int **banks, int *blen, int val) {
int len = *blen;
if (len % 8 == 0) *banks = realloc(*banks, (len+8) * sizeof(int));
int *rbanks = *banks;

rbanks[len] = val;
*blen = len+1;
}

void
push_to_steps(int ***steps, int *slen, int *banks, int blen) {
int len = *slen;
if (len % 8 == 0) *steps = realloc(*steps, (len+8) * sizeof(int *));
int **rsteps = *steps;

int *newbanks = malloc(blen * sizeof(int));
memmove(newbanks, banks, blen * sizeof(int));

rsteps[len] = newbanks;
*slen = len+1;
}

int
steps_index(int **steps, int slen, int *banks, int blen) {
int i = 0, j;
int *step;

start:
while (i < slen) {
step = steps[i];
for (j = 0; j < blen; j++) {
if (step[j] != banks[j]) {
i++;
goto start;
}
}
return i;
}

return -1;
}

struct pos
pop_max(int *banks, int blen) {
int i, max = 0, mi = 0;
for (i = 0; i < blen; i++) {
if (banks[i] > max) {
max = banks[i];
mi = i;
}
}

banks[mi] = 0;
return (struct pos) {max, mi};
}

int
main(int argc, char **argv) {
int *banks = NULL;
int **steps = NULL;
int blen = 0, slen = 0;
int part;

if (argc != 2 || ((part = (*argv[1])-'0') != 1 && part != 2)) {
fprintf(stderr, "Usage: %s [part:1|2]\n", argv[0]);
return 1;
}

int val;
while ((val = next_int()) != EOF) push_to_banks(&banks, &blen, val);

int repeat;
while((repeat = steps_index(steps, slen, banks, blen)) == -1) {
print_banks(banks, blen);
push_to_steps(&steps, &slen, banks, blen);

struct pos pos = pop_max(banks, blen);
for (int i = 1; i <= pos.item; i++) {
banks[(i + pos.index) % blen]++;
}
}

if (part == 1) fprintf(stderr, "Total steps: %d\n", slen);
else fprintf(stderr, "Steps between repeats: %d\n", slen - repeat);

return 0;
}

m712@nextchan:~$ gcc -o day6 day6.c -O3 -ffast-math -funroll-loops -ftree-vectorize -Wall -Wextra -Werror -pedantic -std=c99
m712@nextchan:~$ time ./day6 1 < day6input >/dev/null
Total steps: 4074

real 0m0.044s
user 0m0.041s
sys 0m0.002s

>45ms

Christmas is fucked beyond comprehension. Most of the slowness is due to steps_index, which can be fixed by implementing a hashmap. I'll bother with it tomorrow.


 No.833639>>833647 >>833648 >>834570

>>833633

WEEEEEEEEEEEEEEEEEEEEEEEEW LAD

why is this so fucking verbose? not even my optimized rust version that implements its own hashmap is this fucking long.

is your blazechan code also this shit?


 No.833647

>>833639

verbose?

It's perfectly normal C.

Stylistically, C is all downhill from here, especially as it's ported.


 No.833648>>833650 >>833653

>>833639

C doesn't have that big of an stdlib, therefore you need to imperatively do some stuff.

I read ints from stdin and parse it, while your input is embedded. Plus your parsing is one chain statement whereas mine is 10 lines because no stdlib support (don't really want to use scanf).

Your program is limited to 128 bytes while mine is generic and its limits are your computer's RAM limits.

Out of 12K LOC incl. JS+CSS+HTML, Blazechan is about 5.5K LOC python, 80% of which is SLOC.


 No.833650

>>833648

>128 bytes

Brain melt, i meant 16 ints.


 No.833653>>833662

>>833648

>C doesn't have that big of an stdlib

Then stop using C tbh

>I read ints from stdin and parse it, while your input is embedded.

Changing it to read from stdin wouldn't change the LOC of my Rust solution.

>while mine is generic and its limits are your computer's RAM limits

The challenge states that there are only 16 memory banks

I rate you pajeet/10


 No.833662>>833663 >>833664

>>833653

>Then stop using C tbh

no u

>Changing it to read from stdin wouldn't change the LOC of my Rust solution.

Selectively replying to a statement won't gain you an argument. You use a chain function to parse the input line, which is simpler than the C solution I did. Perhaps I phrased it wrong.

>The challenge states that there are only 16 memory banks

Yes, and? I made my program to take any amount of memory banks. Your solution isn't scalable while mine is. This matters in real world development which these series of code challenges are trying to educate you about.

>I rate you pajeet/10

I rate you "not an argument"/10.


 No.833663

>>833662

polite bump


 No.833664>>833672

>>833662

>This matters in real world development

This is a fucking challenge. Holy shit stop LARPing.

>which these series of code challenges are trying to educate you about.

https://en.wikipedia.org/wiki/Advent_calendar


 No.833672>>833676

>>833664

>This is a fucking challenge. Holy shit stop LARPing.

Keep that mindset, Pajeet. How's that stackoverflow copy&paste job going? Get back to work.

>https://en.wikipedia.org/wiki/Advent_calendar

And?


 No.833674>>833919

Some people take this way too serious. It's just a bunch of puzzles that you solve for fun. All the top rated guys don't give two shits about performance as long as their code is done first.


 No.833676

>>833672

>Keep that mindset, Pajeet.

How am I the pajeet though? You wrote the slow and bloated mess, that does more than it is required to do because "real world development".

>And?

It isn't meant to "educate" about "real world development". It is meant to be a fun little challenge every day until christmas.

https://adventofcode.com/2017/about

>Advent of Code is a series of small programming puzzles for a variety of skill levels. They are self-contained and are just as appropriate for an expert who wants to stay sharp as they are for a beginner who is just learning to code. Each puzzle calls upon different skills and has two parts that build on a theme.


 No.833743>>833768 >>833942

>>833546

>>binary tree

>too slow

Actually no, depending on input it runs well below 1ms:

#include <stdio.h>
#include <alloca.h>
#include <string.h>
#include <stdint.h>
#include <sys/time.h>

const unsigned char INPUT[] = {0, 1, 2, 3, 2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 10};

struct tree {
unsigned char data[16];
struct tree *left;
struct tree *right;
unsigned int step;
};

inline char cmp128(__int128 a, __int128 b)
{
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}

int main()
{
struct timeval start;
struct timeval end;
gettimeofday(&start, NULL);

struct tree history;
memcpy(history.data, INPUT, 16);
history.left = NULL;
history.right = NULL;
history.step = 0;

unsigned int ctr = 0;
unsigned int size;
unsigned char *curdata = history.data;

for (;;) {
ctr++;
struct tree *new = alloca(sizeof(struct tree));
memcpy(new->data, curdata, 16);
new->left = NULL;
new->right = NULL;
new->step = ctr;
curdata = new->data;

unsigned char max_c = 0;
unsigned char max_v = 0;
for (unsigned char i = 0; i < 16; i++) {
if (new->data[i] > max_v) {
max_c = i;
max_v = new->data[i];
}
}

new->data[max_c] = 0;
for (unsigned char i = 0; i < 16; i++) {
new->data[i] += max_v/16;
}
for (unsigned char i = 0; i < max_v%16; i++) {
new->data[(i+max_c+1)%16]++;
}

struct tree *ptr = &history;
for (;;) {
char cmp = cmp128(*((__int128 *) ptr->data), *((__int128 *) new->data));
if (cmp > 0) {
if (ptr->left == NULL) {
ptr->left = new;
break;
} else {
ptr = ptr->left;
}
} else if (cmp < 0) {
if (ptr->right == NULL) {
ptr->right = new;
break;
} else {
ptr = ptr->right;
}
} else {
size = ctr-ptr->step;
goto b;
}
}
}

b:
gettimeofday(&end, NULL);
printf("Part 1: %d\nPart 2: %d\n", ctr, size);
printf("Time: %ld us\n", (end.tv_sec-start.tv_sec)*1000000+end.tv_usec-start.tv_usec);
return 0;
}


 No.833768>>833775

>>833743

Yeah try my input: 4, 10, 4, 1, 8, 4, 9, 14, 5, 1, 14, 15, 0, 15, 3, 5

Your solution takes 7ms with it.


 No.833775

>>833768

On my machine:

>Part 1: 12841

>Part 2: 8038

>Time: 2553 us

But yeah it's not optimal. With the input from >>833471 it runs in 1.2ms, with some guy's numbers I found on reddit (0, 14, 13, 12, 11, 10, 8, 8, 6, 6, 5, 3, 3, 2, 1, 10) it's 0.3ms.


 No.833919

>>833674

>u guys r 2 srs

>ALL THE TOP RATED GUYS THEY SAY

The top rated guys are complete faggots who are too serious about the contest part of the contest, even when it has a design that's blatantly hostile to competition. The discussion you're objecting to is actually productive and beneficial beyond the competition.


 No.833942

>>833546

>>833743

>>>binary tree

You could try a bloom filter.


 No.833979>>833987

Finally day 7 required a bit of thinking to get through.

Still, it's mostly brute force.


import re
from collections import defaultdict

pt = re.compile(r'(\w+) \(([0-9]+)\)(?: -> (.*))?\n?')


def parse_row(l):
m = pt.fullmatch(l)
bottom, bottom_weight, *r = m.groups()
other = r[0].split(', ') if r and r[0] else ()
return bottom, bottom_weight, other


all = set()
not_bottom = set()


class P:
def __init__(self):
self.name = None
self.weight = None
self.parent = None
self.children = None


all_linked = defaultdict(P)

with open('input.txt', 'r') as f:
lines = map(parse_row, f)
for bottom, w, other in lines:
bp: P = all_linked[bottom]
bp.name = bottom
bp.weight = int(w)
bp.children = tuple(map(lambda x: all_linked[x], other))
all.add(bottom)
not_bottom.update(other)

root = all_linked[next((all - not_bottom).__iter__())]
print(root.name)


def calc_weight(root: P):
return root.weight + sum(map(calc_weight, root.children))


def check_weight(root: P):
diff = 0
while True:
weights = tuple(map(calc_weight, root.children))
hst = defaultdict(int)
for w in weights:
hst[w] += 1
hst = tuple(hst.items())
if len(hst) > 1:
wrong_weight = next(filter(lambda x: x[1] == 1, hst))[0]
correct_weight = next(filter(lambda x: x[1] != 1, hst))[0]
wrong_tree_index = next(i for i in range(len(weights)) if weights[i] == wrong_weight)
wrong_tree = root.children[wrong_tree_index]
diff = correct_weight - wrong_weight
root = wrong_tree
else:
return root.weight + diff


print(check_weight(root))


 No.833987

>>833979

total weight could be cached to avoid recalculating it but I didn't bother because it gives answer in a fraction of a second anyway.


 No.833992>>833993 >>834443

day 7. phew.

void recursive_circus1(string input)
{
unordered_set<string_view> has_base, has_no_base;
for (string_view line : input | split(by_line)){
auto [name, rest] = grab_while(line, by_alpha);
if (!has_base.count(name))
has_no_base.insert(name);
for (string_view supported : rest | split(by_alpha)){
if (auto it = has_no_base.find(supported); it != has_no_base.end())
has_no_base.erase(it);
has_base.insert(supported);
}
}
cout << *has_no_base.begin();
}
struct node_t { vector<node_t*> next; int weight, total_weight; };
int needed_weight(node_t* parent)
{
parent->total_weight = parent->weight;
for (node_t* child : parent->next){
if (int nw = needed_weight(child); nw != ~0u)
return nw;
parent->total_weight += child->total_weight;
}
if (parent->next.size() > 2){
auto majority = [&](auto&& f){ return f(0) == f(1) || f(0) == f(2) ? f(0) : f(1); };
int majority_total_weight = majority([&](size_t i){ return parent->next[i]->total_weight; });
for (node_t* child : parent->next){
if (child->total_weight != majority_total_weight)
return child->weight - child->total_weight + majority_total_weight;
}
}
return ~0u;
}
void recursive_circus2(string input)
{
unordered_map<string_view, node_t> tree;
unordered_set<string_view> has_base, has_no_base;
for (string_view line : input | split(by_line)){
auto [name, rest1] = grab_while(line, by_alpha);
auto [ignored, rest2] = grab_while(rest1, not_fn(by_num));
auto [weight, rest] = grab_while(rest2, by_num);
node_t& node = tree[name];
node.weight = stoi(string(weight));
vector<node_t*>& next = node.next;
if (!has_base.count(name))
has_no_base.insert(name);
for (string_view supported : rest | split(by_alpha)){
if (auto it = has_no_base.find(supported); it != has_no_base.end())
has_no_base.erase(it);
has_base.insert(supported);
next.push_back(&tree[supported]);
}
}
cout << needed_weight(&tree[*has_no_base.begin()]);
}
New helper functions:
template<typename P> constexpr auto grab_while(string_view in, P&& p)
{
if (in.empty()) return pair(string_view(), string_view());
size_t cur = 0;
if (p(in[cur])) do ++cur; while(cur < in.size() && p(in[cur]));
return pair(string_view(in.data(), cur), string_view(in.data() + cur, in.size() - cur));
}
bool by_alpha(char c) { return isalpha(c); }
bool by_num(char c) { return isdigit(c); }


 No.833993>>833996

>>833992

wow

is it C++18? or what version?

last time I saw any C++ code it didn't look like that.


 No.833995

days 1-6: avg 10 min to answer second question

day 7: one hour to answer second question

code is complete shit too. I just didn't want to do this one proper. no ocaml today:

utop # List.map (fun x -> total_weight [x]) (Hashtbl.find claims "tdxow");;
- : int list list = [[1184]; [1184]; [1192]]
utop # Hashtbl.find claims "tdxow";;
- : string list = ["mrxqlw"; "htzrkz"; "ghwgd"]
utop # List.map (fun x -> total_weight [x]) (Hashtbl.find claims "ghwgd");;
- : int list list = [[274]; [274]; [274]]
utop # Hashtbl.find names "ghwgd";;
- : int = 370
utop # 274 * 3 + 370;;
- : int = 1192
utop # 1184 - 274 * 3;;
- : int = 362


 No.833996>>833999

>>833993

I'm using C++17.

"std::string_view", "std::not_fn", the "auto [name, rest1] = grab_while(line, by_alpha);" return value decomposition thing and the ability to declare a variable inside the if clause are C++17 features. Lambdas are a C++11 feature (or C++14 when the arguments are generic), and so are "auto" and range-based for loops. Function return type deduction (with auto) is a C++14 feature. The whole "input | split(by_line)" hack comes from the ugly pile of class templates I defined here: >>831584 (also exploits some C++17 features, like how begin() and end() don't have to be the same type in a range-based for loop) (some corrections have been made since I wrote it).

I'm probably forgetting something.


 No.833999>>834007

>>833996

hmmmm that looks interesting.

then how would you write the solution if you were not allowed to use templates beyond simple parametric polymorphism (like in Java or Haskell)?

and in general is C++ worth learning now that it got all this cool stuff? especially with regard to difficulty of writing code that doesn't corrupt memory.

or I'd better create a designated thread for the discussion of modern C++?


 No.834006>>834016

File (hide): 9f1c31fd9d03823⋯.png (287.92 KB, 1098x1152, 61:64, 7a.png) (h) (u)

File (hide): 10b2510e8382df6⋯.png (203.1 KB, 944x978, 472:489, 7b.png) (h) (u)

Mathematica Day 7. The stack weight is being amortized, but that's not necessary as the tree (at least in my input) isn't very deep.


 No.834007

>>833999

>then how would you write the solution if you were not allowed to use templates beyond simple parametric polymorphism (like in Java or Haskell)?

Everything here is parametric polymorphism + function/operator overloading, though. I'm not using any template specialization or weird metaprogramming tricks (i.e. "SFINAE") here. In the newest version of >>831584 , I'm using a type trait in one place, but that's it. If you mean without any of >>831584 at all, I might do something like this (untested):

for (string_view line, rest = input; tie(line, rest) = grab_while(rest, by_line), !line.empty();){
//do other transformations on line here
//...
}
("tie" is a standard library function).

>and in general is C++ worth learning now that it got all this cool stuff?

I think so, though it's a lot to learn. And in C++20 a lot more useful things are going to be added, like coroutines, modules, concepts, networking (I think) and possibly some basic reflection.

>especially with regard to difficulty of writing code that doesn't corrupt memory.

Depending on what you do, you may still have to be careful (for instance, in recursive_circus2 I'm storing node_t* pointers to elements inside an unordered_map, then adding new elements with "tree[name]", which is only correct because calling unordered_map's operator[] doesn't invalidate references; if for example I was pushing those nodes into a vector instead, I couldn't have done that). Still, I think modern C++ is a lot better than C or old C++ in that regard (e.g. memory leaks are easy to avoid using std::unique_ptr, string buffer overflows/corruption are easy to avoid with std::string and std::string_view, etc.).

>or I'd better create a designated thread for the discussion of modern C++?

If this conversation gets too large, I guess.


 No.834011>>834015

File (hide): 28a5fd2faf17792⋯.png (51.97 KB, 392x364, 14:13, d7stats.png) (h) (u)

Day 7 has only been available for 3 hours 20 mins, so this'll certainly grow, but that's still quite small compared to other days by this time. Also notice that there's quite a lot of Part A people here, showing that Part B is proving to be a stumbling block for many.

(reposting with image)


 No.834013>>834115

#!/usr/bin/env python3
# Copyright m712 2017.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import sys
import re
import collections

class Tree(object):
def __init__(self, name, weight, children):
self.name = name
self.weight = weight
self.children = children
self.parent = None

def __repr__(self):
return "<{:s}: {:s}>".format(type(self).__name__, str(self))

def __str__(self):
return "{:s} ({:d}) -> {:d} children".format(self.name, self.weight,
len(self.children))

def parse(input):
trees = {}
for line in filter(lambda x: x, input.split('\n')):
# name (weight) -> a, b, c
words = line.split(' ', 3)
name, weight, children = (words[0],
int(re.sub(r'\((\d+)\)', r'\1', words[1])),
[] if len(words) < 3 else
list(map(str, words[3].split(', '))))
trees[name] = Tree(name, weight, children)

for t in trees.values():
t.children = list(map(lambda x: trees[x], t.children))
for c in t.children: c.parent = t

return list(trees.values())

def part1(trees):
def climb(tree):
if not tree.parent:
# at the top
return tree
else:
return climb(tree.parent)

return climb(trees[0])

def total_weight(tree):
return tree.weight + sum(map(total_weight, tree.children))

def average(tree):
return (tree.total_weight - tree.weight) // len(tree.children)

def calc_weights(tree):
tree.total_weight = total_weight(tree)
for t in tree.children:
calc_weights(t)

def part2(tree):
calc_weights(tree)
parent = tree
diff = None

while True:
commons = collections.Counter(t.total_weight for t in parent.children
).most_common()

print(parent, commons, diff)

if len(commons) == 1:
return parent.weight - diff

diff = commons[1][0] - commons[0][0]

parent = list(filter(lambda t: t.total_weight == commons[1][0],
parent.children))[0]

if __name__ == "__main__":
print('Enter tree:')
trees = parse(sys.stdin.read())
print('Top of tree:', part1(trees).name)
print('Correct value:', part2(part1(trees)))

m712@nextchan:~$ time python3 day7.py <day7input >/dev/null

real 0m0.095s
user 0m0.072s
sys 0m0.008s

C version coming after the Py3 implementation.


 No.834015>>834016 >>834258

File (hide): 2b5c9370329db98⋯.jpg (34.58 KB, 460x276, 5:3, shitcoders.jpg) (h) (u)

>>834011

Pajeets having trouble traversing a tree


 No.834016

>>834006

>amortized

Ugh I meant memoized

>>834015

They're just waiting for the Java solution to be posted on reddit so they can copy+paste into Eclipse.


 No.834112>>834114 >>834115 >>834540

/**
* Copyright m712 2017.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>

typedef struct _node {
char *name;
__uint128_t hash;
int weight, total_weight;

struct _node **children;
int clen;

char **raw_children;
int rlen;

struct _node *parent;
} Node;

#define GROW_CHUNK 8
#define CHECK_SIZE(type, arr, len) \
do { \
if ((len) % GROW_CHUNK == 0) \
(arr) = realloc((arr), \
((len)+GROW_CHUNK) * sizeof(type)); \
} while (0)

#define PUSH(type, arr, len, item) \
do { \
CHECK_SIZE(type, arr, len); \
(arr)[len] = (item); \
(len)++; \
} while (0)

#define DESTROY(arr, len, i) \
do { \
for (i = 0; i < len; i++) \
free(arr[i]); \
free(arr); \
} while (0)

#define EXPLODE(str, ...) \
do { \
printf("\033[0m" str "\n", __VA_ARGS__); \
abort(); \
} while (0)

/**
* a-z = 27 combinations.
* This hash implementation supports up to 25 characters + 4 lower bits.
* Case-insensitive
*/
#define HASH(str, hash) \
do { \
int len = strlen(str); \
for (int hi = 0; hi < len; hi++) \
hash |= ((__uint128_t) ((tolower(str[hi]) - 'a') & 0x1F)) \
<< (5 * hi); \
} while (0)

char *
get_word(void) {
char *str = NULL;
int len = 0;
int c;
while (isalnum((c = getchar())))
PUSH(char *, str, len, c);

PUSH(char *, str, len, 0);

ungetc(c, stdin);
return str;
}

int
get_int(void) {
int val = 0;
int c;
while (isdigit((c = getchar()))) {
val = 10*val + (c - '0');
}

ungetc(c, stdin);
return val;
}

static int line;

Node *
node_from_line() {
line++;

// name (weight) -> children,
Node *node = calloc(1, sizeof(Node));
CHECK_SIZE(char **, node->raw_children, 0);
int c;

node->name = get_word();
HASH(node->name, node->hash);
getchar(); // space
c = getchar(); // (
if (c != '(')
EXPLODE("Expected ( at line %d", line);


node->weight = get_int();
getchar(); // )

c = getchar(); // " ->" or \n or EOF
if (c == '\n' || c == EOF) {
CHECK_SIZE(Node *, node->children, 0); // initialize
return node;
} else if (c != ' ' || getchar() != '-' || getchar() != '>')
EXPLODE("Expected -> or newline at line %d", line);

getchar(); // space

for (;;) {
PUSH(char **, node->raw_children, node->rlen, get_word());
c = getchar(); // \n or EOF or ", "
if (c == '\n' || c == EOF) {
return node;
} else if (c != ',' || getchar() != ' ')
EXPLODE("', ' or newline expected at line %d", line);
}
}

Node *
find_node(Node **nodes, int len, const char *name) {
__uint128_t hash = 0;
HASH(name, hash);
for (int i = 0; i < len; i++)
if (nodes[i]->hash == hash)
return nodes[i];

return NULL;
}

1/3


 No.834113>>834114

void
resolve_tree(Node **nodes, int len) {
for (int i = 0; i < len; i++) {
Node *node = nodes[i];
for (int j = 0; j < node->rlen; j++) {
Node *child = find_node(nodes, len, node->raw_children[j]);
if (!child)
EXPLODE("Node '%s' references unknown child '%s'",
node->name, node->raw_children[i]);
PUSH(Node **, node->children, node->clen, child);
child->parent = node;
}
int di;
DESTROY(node->raw_children, node->rlen, di);
}
}

int
calc_total_weight(Node *node) {
int weight = node->weight;
for (int i = 0; i < node->rlen; i++)
weight += calc_total_weight(node->children[i]);
node->total_weight = weight;
return weight;
}

Node *
get_root(Node *node) {
if (!node->parent) return node;
return get_root(node->parent);
}

char *
part1(Node *root) {
return root->name;
}

struct uniq {
int weight, count;
};

#define MOVU(a,b) \
a.weight = b.weight; \
a.count = b.count;

void
get_commons(Node **nodes, int len, struct uniq commons[2]) {
struct uniq temp;
for (int i = 0; i < len; i++) {
Node *node = nodes[i];
if (commons[0].weight == 0) {
commons[0].weight = node->total_weight;
commons[0].count++;
} else if (commons[0].weight == node->total_weight) {
commons[0].count++;
} else if (commons[1].weight == 0) {
commons[1].weight = node->total_weight;
commons[1].count++;
} else if (commons[1].weight == node->total_weight) {
commons[1].count++;
} else EXPLODE("Third weight %d?!", node->total_weight);
}

if (commons[1].count > commons[0].count) {
// Swap
MOVU(temp, commons[1]);
MOVU(commons[1], commons[0]);
MOVU(commons[0], temp);
}
}

int
part2(Node *root) {
calc_total_weight(root);

struct uniq commons[2] = {{0, 0}};
int diff = 0;

Node *parent = root;

for (;;) {
commons[0].weight = 0;
commons[0].count = 0;
commons[1].weight = 0;
commons[1].count = 0;
get_commons(parent->children, parent->clen, commons);

if (commons[1].count == 0)
return parent->weight - diff;

diff = commons[1].weight - commons[0].weight;
for (int i = 0; i < parent->clen; i++)
if (parent->children[i]->total_weight == commons[1].weight)
parent = parent->children[i];
}
}

int
main(int argc, char **argv) {
Node **nodes = NULL;
int part;
int len = 0;

if (argc != 2 || !((part = *argv[1] - '0') == 1 || part == 2)) {
fprintf(stderr, "Usage: %s [part:1|2]\n", argv[0]);
return 1;
}

int c;
for (;;) {
PUSH(Node **, nodes, len, node_from_line());

if ((c = getchar()) == EOF || c == '\n') break;
else ungetc(c, stdin);
}
resolve_tree(nodes, len);

if (part == 1)
printf("Name of root: %s\n", part1(get_root(nodes[0])));
else
printf("Required weight: %d\n", part2(get_root(nodes[0])));

int j;
for (int i = 0; i < len; i++) {
Node *node = nodes[i];
free(node->children);
free(node->name);
}
DESTROY(nodes, len, j);

return 0;
}

m712@ion ~ % time ./day7 1 < day7input
Name of root: vvsvez
./day7 1 < day7input 0.00s user 0.00s system 97% cpu 0.007 total
m712@ion ~ % time ./day7 2 < day7input
Required weight: 362
./day7 2 < day7input 0.01s user 0.00s system 96% cpu 0.007 total

2/2

>7ms

F

Valgrind shows no leaks. This time I used a hashmap.


 No.834114

>>834112

>>834113

Don't you know what a pastebin is?


 No.834115>>834116

File (hide): 5db39aaef5ec67c⋯.jpg (53.53 KB, 960x539, 960:539, 1504168792888.jpg) (h) (u)

>>833633

>>834013

>>834112

>GPL header

Made me smile


 No.834116>>834125

>>834115

I want everyone to be able to modify and study my code and share modified versions of it. This is why I chose GPL3. The copyright notices are there because by default the code license is "All rights reserved" under many jurisdictions which restricts your freedom.


 No.834125>>834127

>>834116

Do you want me to modify and study your comment?


 No.834127

>>834125

As long as you preserve my copyright notice and the license notice, you are permitted to modify everything.


 No.834169>>834175 >>834181

>rustfag still hasn't posted

LOL @ language that doesn't allow doubly linked lists

LOL @ language can't have trees with parents

LOL @ safety from using it for anything but toy projects


 No.834175>>834181 >>834452

>>834169

>>rustfag still hasn't posted

Yeah my solution is beyond pajeet level (also I have accidentally deleted it). I'm rewriting it currently.

>LOL @ language that doesn't allow doubly linked lists

https://doc.rust-lang.org/std/collections/struct.LinkedList.html

How is this relevant to this challenge?

>LOL @ language can't have trees with parents

Why would you ever do that? Also, how is this relevant to the challenge?

>LOL @ safety from using it for anything but toy projects

https://en.wikipedia.org/wiki/Rust_(programming_language)#Projects_using_Rust


 No.834181>>834190

>>834169

>>834175

Yeah fuck the borrow checker... Butt ugly. Part 1 works.

extern crate regex;

use std::fs::File;
use std::io::{BufRead,BufReader};
use std::collections::HashMap;
use regex::Regex;

struct Program {
parent: Option<String>,
weight: u32,
}

fn main() {
let mut tree = HashMap::new();
let file = File::open("input").unwrap();
let re1 = Regex::new("^(\\w+) \\((\\d+)\\)").unwrap();
let re2 = Regex::new(" (\\w+)").unwrap();
for line in BufReader::new(file).lines() {
let line = line.unwrap();
let c = re1.captures(&line).unwrap();
if !tree.contains_key(&c[1]) {
tree.insert(String::from(&c[1]), Program {
parent: None,
weight: c[2].parse::<u32>().unwrap(),
});
} else {
tree.get_mut(&c[1]).unwrap().weight = c[2].parse::<u32>().unwrap();
}
for d in re2.captures_iter(&line) {
if !tree.contains_key(&d[1]) {
tree.insert(String::from(&d[1]), Program {
parent: Some(String::from(&c[1])),
weight: 0,
});
} else {
tree.get_mut(&d[1]).unwrap().parent = Some(String::from(&c[1]));
}
}
}
{
let mut ptr = tree.iter().next().unwrap().0;
while let Some(ref x) = tree.get(ptr).unwrap().parent {
ptr = &x;
}
println!("Part 1: {}", ptr);
}

for p in tree.iter_mut() {
if let Some(ref parent) = p.1.parent {
tree.get_mut(parent).unwrap().weight += p.1.weight;
}
}
}


 No.834190>>834201

>>834181

> fuck the borrow checker

Isn't that Rust's greatest ally?


 No.834201

>>834190

It's what is supposed to make Rust safe. It is also the reason why Pajeets will never be able to write Rust.


 No.834203>>834204 >>834246

File (hide): b09114b04d87ad0⋯.png (52.11 KB, 392x364, 14:13, oy.png) (h) (u)

Day 7 is proving to be a Pajeet Shoah. Now it is 13 hours, 29 minutes since the solution has been posted, which is more than enough to account for Pajeet to get to the solution.

India is 10 and a half hours ahead of EST, so if Pajeet isn't neet and can't work at lunch, he can get started 6 and a half hours after the problem is posted (assuming he finishes work at 5pm and rides his rickshaw very rapidly to his designated coding street).


 No.834204

>>834203

Should have been 42 minutes, was distracted before hitting send.


 No.834246>>834284

>>834203

Why do you keep posting these? Do you expect people to solve silly challenges on a workday? As you can see the numbers even out after a while when people catch up on the challenges.

Normal people have a life and work and can't spend every waking minute solving stupid challenges on the internet like you neetscum.


 No.834258>>834262

>>834015

>coders

>guys in the background clearly not doing coding

well done


 No.834262

>>834258

>>guys in the background clearly not doing coding

But the guys in the front are.

Prove me wrong.


 No.834272>>834275 >>834285 >>834452

Fuck this bullshit. I hate this language.

extern crate regex;

use std::fs::File;
use std::io::{BufRead,BufReader};
use std::collections::HashMap;
use regex::Regex;

struct Program {
parent: Option<String>,
weight: u32,
}

fn get_children<'a>(tree: &'a HashMap<String, Program>, node: &'a str) -> Vec<String> {
let mut result = vec![];
for x in tree.iter().filter(|&i| i.1.parent == Some(node.to_string())) {
result.push(x.0.clone());
}
result
}

fn get_weight(tree: &HashMap<String, Program>, node: &str) -> u32 {
get_children(tree, node).iter().fold(tree.get(node).unwrap().weight, |acc, x| acc + get_weight(tree, x))
}

fn get_parent(tree: &HashMap<String, Program>, node: &str) -> String {
let x = tree.get(node).unwrap();
let x = x.parent.clone();
x.unwrap()
}

fn find_unbalanced<'a>(tree: &'a HashMap<String, Program>, node: &'a str) -> String {
let mut x = get_children(tree, node).iter().map(|x| (x.clone(), get_weight(tree, &x))).collect::<Vec<(String, u32)>>();
x.sort_by_key(|x| x.1);
if x.len() >= 3 {
if x.first().unwrap().1 == x.last().unwrap().1 {
String::from(node)
} else if x.first().unwrap().1 == x[1].1 {
find_unbalanced(&tree, &x.last().unwrap().0)
} else {
find_unbalanced(&tree, &x.first().unwrap().0)
}
} else {
String::from(node)
}
}

fn main() {
let mut tree = HashMap::new();
let file = File::open("input").unwrap();
let re1 = Regex::new("^(\\w+) \\((\\d+)\\)").unwrap();
let re2 = Regex::new(" (\\w+)").unwrap();
for line in BufReader::new(file).lines() {
let line = line.unwrap();
let c = re1.captures(&line).unwrap();
if !tree.contains_key(&c[1]) {
tree.insert(String::from(&c[1]), Program {
parent: None,
weight: c[2].parse::<u32>().unwrap(),
});
} else {
tree.get_mut(&c[1]).unwrap().weight = c[2].parse::<u32>().unwrap();
}
for d in re2.captures_iter(&line) {
if !tree.contains_key(&d[1]) {
tree.insert(String::from(&d[1]), Program {
parent: Some(String::from(&c[1])),
weight: 0,
});
} else {
tree.get_mut(&d[1]).unwrap().parent = Some(String::from(&c[1]));
}
}
}
let mut ptr = tree.iter().next().unwrap().0;
while let Some(ref x) = tree.get(ptr).unwrap().parent {
ptr = &x;
}
println!("Part 1: {}", ptr);

let x = get_children(&tree, &get_parent(&tree, &find_unbalanced(&tree, ptr)));
let mut y = x.iter().map(|x| (x, get_weight(&tree, &x))).collect::<Vec<(&String, u32)>>();
y.sort_by_key(|x| x.1);
if y.first().unwrap().1 == y[1].1 {
println!("Part 2: {}", tree.get(y.last().unwrap().0).unwrap().weight - (y.last().unwrap().1 - y[1].1));
} else {
println!("Part 2: {}", tree.get(y.first().unwrap().0).unwrap().weight + (y[1].1 - y.first().unwrap().1));
}
}


 No.834275

File (hide): 6cfd54ced4fcf1a⋯.gif (1.47 MB, 210x144, 35:24, 1462424929295.gif) (h) (u)

>>834272

this is worse than c++


 No.834284>>834288

>>834246

>stats aren’t interesting

I know you are upset Pajeet, but try and apply a little thinking. There is a clear downward trend, where the decline is accentuated by the presence of relatively harder problems.

These are only stupid challenges to pleb coders who will never master their craft.


 No.834285>>834291

>>834272

>all these fucking ".unwrap()" everywhere

Very memory-safe :^)

>iterating through a hash map and filtering on names to find a node's children

Just use pointers, man.


 No.834288>>834291 >>834328

>>834284

>day 3 is difficult

>day 4 and 5 are easy

>relatively harder problems

you're retarded, people are busy writing code for money instead of wasting time doing shit for free


 No.834291>>834301 >>834304

>>834285

>Very memory-safe :^)

Yes because it just crashes if .unwrap() fails

>Just use pointers, man.

No, that would be unsafe.

>>834288

As if your neet time was worth anything


 No.834301

>>834291

what does my time have to do with other people working?


 No.834304

>>834291

>loading up code with dumb syntax noise is the right way to assuage my memory-safety paranoia

t. delusional fanatic

>Who cares about performance? Muh safety!

Might as well use a garbage-collected language.


 No.834328

File (hide): d2fb9df9068bde7⋯.jpeg (30.81 KB, 561x333, 187:111, white man.JPEG) (h) (u)

>>834288

> instead of wasting time doing shit for free

Despite you dubs, we now know you're not a white man. It's just a mentality you will never, ever understand. We go far beyond what is mandated of us, it is why our people have created beautiful civilizations whilst your people live in a squalor which can at best be describe as a failed attempt at a British cargo cult. It is why our people sailed the high seas, went to the moon, and solve AdventOfCode problems; whereas you lack basic infrastructure. Perhaps it wasn't always this way with your people, but being plagued by pettiness and unscrupulousness directed amongst your own kin has rendered your civilization dysfunctional.


 No.834438>>834452

Cheating with eval


import re
from collections import defaultdict
ws = re.compile(r'\s+')
def parse_row(l):
p = ws.split(l)
return p[0], p[1], p[2], p[4], p[5], p[6]
vs = defaultdict(lambda: 0)
m = 0
with open('input.txt', 'r') as f:
lines = map(parse_row, f)
for t, op, d, c, cmp, cmpv in lines:
if eval(f'{c} {cmp} {cmpv}', None, vs):
vs[t] += int(d) * (1 if op == 'inc' else -1)
m = max(m, vs[t])
print(max(vs.values()), m)


 No.834440>>834441

Day 8 Golfed

203 characters


import collections as C
v=C.defaultdict(int)
m=0
for t,p,d,_,c,o,z in map(lambda l:l.split(' '),open('i')):
if eval(c+o+z,None,v):v[t]+=int(d)*(1if p=='inc'else-1);m=max(m,v[t])
print(max(v.values()),m)


 No.834441>>834444

>>834440

200 characters

ditched 'if' statement because I can implicitly convert bool to int


import collections as C
v=C.defaultdict(int)
m=0
for t,p,d,_,c,o,z in map(lambda l:l.split(' '),open('i')):
v[t]+=eval(c+o+z,None,v)*int(d)*(1if p=='inc'else-1);m=max(m,v[t])
print(max(v.values()),m)


 No.834443>>834463

>>833992

day 8. Nothing fancy.

void heard_you_like_registers(string input)
{
unordered_map<string_view, int> reg;
auto compare = [](int a, string_view op, int b){
return op == "==" ? a == b : op == "!=" ? a != b :
op == "<" ? a < b : op == "<=" ? a <= b :
op == ">" ? a > b : a >= b;
};
int highest = int((~0u >> 1) + 1);
for (string_view line : input | split(by_line)){
auto [modif, ins, q, x, compreg, comp, compval, rest] = parse_only(line, by_alpha, by_alpha, by_int, by_alpha, by_alpha, by_word, by_int);
if (compare(reg[compreg], comp, stoi(string(compval))))
if (int cur = reg[modif] += stoi(string(q)) * (ins == "inc" ? 1 : -1); cur > highest)
highest = cur;
}
cout << "part 1: " << max_element(reg.begin(), reg.end(), [](auto&& a, auto&& b){ return a.second < b.second; })->second << '\n';
cout << "part 2: " << highest << '\n';
}
New helper functions for today, building on previously made grab_while to parse multiple things:
template<typename... Ps, size_t... n> constexpr auto parse_only_impl(index_sequence<n...>, string_view in, Ps&&... ps)
{
array<string_view, sizeof...(ps) + 1> res;
((tie(res[n], in) = grab_while(in, not_fn(forward<decltype(ps)>(ps))),
tie(res[n], in) = grab_while(in, forward<decltype(ps)>(ps))), ...);
res[sizeof...(ps)] = in;
return res;
}
template<typename... Ps> constexpr auto parse_only(string_view in, Ps&&... ps)
{
return parse_only_impl(index_sequence_for<Ps...>{}, in, forward<Ps>(ps)...);
}
bool by_int(char c) { return isdigit(c) || c == '-'; }


 No.834444>>834576

>>834441

197 characters

no need to compare strings by equality here :D


import collections as C
v=C.defaultdict(int)
m=0
for t,p,d,_,c,o,z in map(lambda l:l.split(' '),open('i')):
v[t]+=eval(c+o+z,None,v)*int(d)*(1if p>'i'else-1);m=max(m,v[t])
print(max(v.values()),m)


 No.834452>>834453 >>834517

#!/usr/bin/env python3
# Copyright m712 2017.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import sys

def parse(input):
regs = {}
instrs = []
for line in filter(lambda x: x, input.split('\n')):
reg, instr, by, _, oreg, comp, onum = line.split(' ')
regs[reg] = 0
instrs.append([reg, instr, by, oreg, comp, onum])
return (regs, instrs)

def run(regs, instrs):
mv = 0
comps = {
"<": lambda a,b: a<b,
">": lambda a,b: a>b,
"==": lambda a,b: a==b,
"<=": lambda a,b: a<=b,
">=": lambda a,b: a>=b,
"!=": lambda a,b: a!=b,
}
for i in instrs:
reg, instr, by, oreg, comp, onum = i

if comp not in comps:
raise ValueError("Unknown comparison {}".format(comp))
if not comps[comp](regs[oreg], int(onum)):
continue

if instr == "inc":
regs[reg] += int(by)
elif instr == "dec":
regs[reg] -= int(by)
else:
raise ValueError("Unknown instruction {}".format(instr))

mv = max(mv, regs[reg])

return (regs, mv)

if __name__ == "__main__":
print("Enter input:")
regs, mv = run(*parse(sys.stdin.read()))
print("Maximum register:", max(regs.values()))
print("Maximum value a register has had:", mv)

Did a shitty version of this in a repl in ~15 minutes and got 364th and 447th worldwide respectively. C version should come fairly soon.

>>834272

>all those duplicate strings

>.unwrap() a million times

>while let Some(ref x) = tree.get(ptr).unwrap().parent

>iterating over the tree to get the parent

BEYOND WORDS

>>834175

>Why would you ever do that? Also, how is this relevant to the challenge?

>why would you use a thing that makes part 1 O(log(n))

>>834438

>Cheating with eval

Cheating is for niggers.


 No.834453


 No.834460>>834464

File (hide): 6c9c6d781729ef7⋯.png (148.96 KB, 1098x1016, 549:508, day8.png) (h) (u)

Mathematica. This is a simple one for any language with first class functions.


 No.834463>>834466 >>834979

>>834443

Slightly modified to make comparison more efficient and use a more appropriate parsing function:

void heard_you_like_registers(string input)
{
unordered_map<string_view, int> reg;
auto compare = [](int a, string_view op, int b){
return op[0] == '=' ? a == b :
op[0] == '!' ? a != b :
op[0] == '<' ? (op.size() == 1 ? a < b : a <= b) :
(op.size() == 1 ? a > b : a >= b);
};
int highest = int((~0u >> 1) + 1);
for (string_view line : input | split(by_line)){
auto [modif, ins, val, if_, compreg, comp, compval, rest] = parse_n<7>(line, by_word);
if (compare(reg[compreg], comp, stoi(string(compval))))
if (int cur = reg[modif] += stoi(string(val)) * (ins == "inc" ? 1 : -1); cur > highest)
highest = cur;
}
cout << "part 1: " << max_element(reg.begin(), reg.end(), [](auto&& a, auto&& b){ return a.second < b.second; })->second << '\n';
cout << "part 2: " << highest << '\n';
}
parse_n:
template<typename P, size_t... n> constexpr auto parse_n_impl(index_sequence<n...>, string_view in, P&& p)
{
array<string_view, sizeof...(n) + 1> res;
((tie(res[n], in) = grab_while(in, not_fn(p)),
tie(res[n], in) = grab_while(in, p)), ...);
res[sizeof...(n)] = in;
return res;
}
template<size_t n, typename P> constexpr auto parse_n(string_view in, P&& p)
{
return parse_n_impl(make_index_sequence<n>{}, in, forward<P>(p));
}


 No.834464>>834473 >>834488

>>834460

Still longer than Python with 197 characters.


 No.834466>>834470

>>834463

I guess I can also replace the

ins == "inc"
with
ins[0] == 'i'
, while I'm at it.


 No.834470>>834475

>>834466

It would be longer by 1 character if you don't count removable whitespace.


 No.834473

>>834464

And I didn't get quads either, but such is life.


 No.834475>>834476

>>834470

I was more going for efficiency than code length for that one, though.


 No.834476>>834478

>>834475

It is irrelevant here. Even python solution finishes in a blink of an eye or faster.

That's autism.


 No.834477>>834480 >>834538

Wtf I love Rust now https://play.rust-lang.org/?gist=7487acd162ae615a85dca98654c2d889&version=stable

extern crate regex;

use std::fs::File;
use std::io::{BufRead,BufReader};
use std::collections::HashMap;
use regex::Regex;

fn main() {
let mut registers: HashMap<String, i32> = HashMap::new();
let file = File::open("input").unwrap();
let re = Regex::new("^(\\w+) (\\w+) (-?\\d+) if (\\w+) ([!<>=]{1,2}) (-?\\d+)$").unwrap();
let mut max = 0;
for line in BufReader::new(file).lines() {
let line = line.unwrap();
let c = re.captures(&line).unwrap();
if match &c[5] {
"==" => *registers.get(&c[4]).unwrap_or(&0) == c[6].parse::<i32>().unwrap(),
"!=" => *registers.get(&c[4]).unwrap_or(&0) != c[6].parse::<i32>().unwrap(),
"<=" => *registers.get(&c[4]).unwrap_or(&0) <= c[6].parse::<i32>().unwrap(),
">=" => *registers.get(&c[4]).unwrap_or(&0) >= c[6].parse::<i32>().unwrap(),
"<" => *registers.get(&c[4]).unwrap_or(&0) < c[6].parse::<i32>().unwrap(),
">" => *registers.get(&c[4]).unwrap_or(&0) > c[6].parse::<i32>().unwrap(),
_ => panic!(),
} {
let r = registers.entry(String::from(&c[1])).or_insert(0);
match &c[2] {
"inc" => *r += c[3].parse::<i32>().unwrap(),
"dec" => *r -= c[3].parse::<i32>().unwrap(),
_ => panic!(),
}
max = std::cmp::max(*r, max);
}
}
let part1 = *registers.values().max().unwrap();
println!("Part 1: {}", part1);
println!("Part 2: {}", std::cmp::max(part1, max));
}


 No.834478>>834479

>>834476

You know what's also autistic?

<It would be longer by 1 character if you don't count removable whitespace.

My flavor of autism is better than yours.


 No.834479>>834481

>>834478

Code golf is a legitimate thing btw.


 No.834480>>834487

>>834477

Show us the day 7 solution in Rust which is not ugly as fuck.


 No.834481

>>834479

And so is optimization tbh fam.


 No.834487>>834493 >>834578

>>834480

Here u go fam

use std::fs::File;
use std::io::{BufRead,BufReader};
use std::collections::HashMap;

fn main() {
let mut registers = HashMap::new();
let mut max = 0;

let file = File::open("input").unwrap();
for line in BufReader::new(file).lines() {
let line = line.unwrap();
let c: Vec<&str> = line.split(' ').collect();

let a = *registers.get(c[4]).unwrap_or(&0);
let b = c[6].parse::<i32>().unwrap();
let d = c[2].parse::<i32>().unwrap();
if match c[5] {
"==" => a == b,
"!=" => a != b,
"<=" => a <= b,
">=" => a >= b,
"<" => a < b,
">" => a > b,
_ => panic!(),
} {
let r = registers.entry(String::from(c[0])).or_insert(0);
match c[1] {
"inc" => *r += d,
"dec" => *r -= d,
_ => panic!(),
}
max = std::cmp::max(*r, max);
}
}

println!("Part 1: {}", registers.values().max().unwrap());
println!("Part 2: {}", max);
}


 No.834488>>834505

File (hide): d8cbc9a74dc68af⋯.png (109.02 KB, 1044x762, 174:127, day8-2.png) (h) (u)

>>834464

Haven't golfed variable names, but getting smaller...


 No.834493>>834495

>>834487

I said day 7


 No.834495

>>834493

Oh right. No. Maybe Steve will.


 No.834505

File (hide): 0b7908a83c5cdaa⋯.png (106.09 KB, 1132x718, 566:359, day8-3.png) (h) (u)

>>834488

A bit smaller removing that switch. Forgive me, but also posted this version on reddit.


 No.834517>>834534 >>834576

>>834452

>filter(lambda x: x, input.split('\n'))

Why don't you just input.splitlines()?


 No.834534

>>834517

Meh. I could use splitlines. I didn't know about it. The filter is there to strip empty lines.

Also, I'm dumb and didn't read the pydoc3 for filter. Passing None should do it.

>>> input = open("day7input").read().splitlines()
>>> input
["ughg (88)", "zhnk (35) -> ughg, nzms, aaj", ..., ""]
>>> # See the empty string at the end which fucks up the parser
>>> filter(None, input)
["ughg (88)", "zhnk (35) -> ughg, nzms, aaj", ..., "deutsch (1488) -> hitler"]


 No.834535>>834577

Day 7: https://play.rust-lang.org/?gist=cba1239b4aa56b484c607c61e7a6b637

Time: 0.86 ms

>inb4 Rc<RefCell<Program>>

The only reason I did that is because I wanted to try out the std::cell module. It is not necessary to do that. A lot of time is probably spent checking accesses inside of RefCell. Going to see how much faster it is with UnsafeCell later today.

Day 8: https://play.rust-lang.org/?gist=20bb760159cbd1ff5d5479c96f52c6e1

Time: 0.38 ms

Pretty verbose. I'm probably going to make it shorter later today.


 No.834538>>834540 >>834547

>>834477

m712@warp ~ % grep unwrap day8.rs | wc -l
13


 No.834540>>834545 >>834564

>>834538

>muh LOC

LOL. >>834112 >>834113

stfu you stupid turkoachh


 No.834545>>834564

>>834540

Shit. I only looked at 'wc -l' and didn't realize you were grepping for unwrap.

How is this worse than using Exceptions for control flow? Kill yourself retarded python nigger.


 No.834547>>834564

>>834538

grep unwrap >>834487 | wc -l
6

So? Would you rather prefer undefined behavior?


 No.834564>>834565 >>834566 >>834567 >>834578 >>834587

>>834540

>stfu you stupid turkoachh

>oachh

Please, it's turkroach.

>>834545

>How is this worse than using Exceptions for control flow? Kill yourself retarded python nigger.

match &c[5] {
"==" => *registers.get(&c[4]).unwrap_or(&0) == c[6].parse::<i32>().unwrap(),
"!=" => *registers.get(&c[4]).unwrap_or(&0) != c[6].parse::<i32>().unwrap(),
"<=" => *registers.get(&c[4]).unwrap_or(&0) <= c[6].parse::<i32>().unwrap(),
">=" => *registers.get(&c[4]).unwrap_or(&0) >= c[6].parse::<i32>().unwrap(),
"<" => *registers.get(&c[4]).unwrap_or(&0) < c[6].parse::<i32>().unwrap(),
">" => *registers.get(&c[4]).unwrap_or(&0) > c[6].parse::<i32>().unwrap(),
_ => panic!(),
}


comps = {
"<": lambda a,b: a<b,
">": lambda a,b: a>b,
"==": lambda a,b: a==b,
"<=": lambda a,b: a<=b,
">=": lambda a,b: a>=b,
"!=": lambda a,b: a!=b,
}
...
if comp not in comps:
raise ValueError("Unknown comparison {}".format(comp))
if not comps[comp](regs[oreg], int(onum)):
continue

You tell me.

>>834547

I'd prefer a language that doesn't add to the work. Rust "removes" the baggage of memory safety woes but then adds back twice the baggage with ass-backwards "safety" calls and the hellspawn known as borrowck.


 No.834565>>834567

>>834564

Not to mention your code will explode with a generic error making it harder to debug while the python code will tell you what the unknown comparison was.

polite sage


 No.834566>>834568 >>834570

>>834564

>oh look. a good thread on /tech/

>lets go into it and post pajeet supreme solutions so long that i have to split them up

>oh look. rust code.

>MUH UNWRAP

the moment you posted in this thread it turned to shit. fuck off turkroach


 No.834567>>834569 >>834575 >>834578

>>834564

>>834565

Also, memory safety has been a solved thing for many years now. Use reference counting. If you have something that's allocated in your struct by another place remember to unref when freeing. It's this simple. Those who can't do something this simple should just stick to interpreted languages or garbage collectors.

polite sage again


 No.834568

>>834566

>good thread

>shilling for some reddit "puzzle" crap

lmfao


 No.834569>>834571

>>834567

>reference counting

as i said: pajeet

polite sage. im going to stop engaging you now.


 No.834570

>>834566

Shut the fuck up. You were the one who started this flamewar about languages. Nobody even shat on others' code until you came in at >>833639 and started shitposting.


 No.834571>>834603

>>834569

>refcounting is bad

pic related

Give one argument against it.


 No.834575

>>834567

>interpreted languages

>Use reference counting

How the fuck are these 2 things connected? Also there's no such thing as compiled or interpreted language.

You don't know what you're talking about dood.


 No.834576

>>834517

why use splitlines at all if you can simply iterate the file like in >>834444

?


 No.834577

>>834535

> Rc<RefCell<…

lol


 No.834578>>834581

>>834564

>>834567

Please see my updated solution in >>834487. None of the unwraps is used to solve a problem that could be solved using reference counting.

>let file = File::open("input").unwrap();

Rust doesn't have exceptions. open returns an `Option` which can either contain a `File` or it can be `None`. unwrap gets the File (if open was successful) or crashes the program.

>let line = line.unwrap();

No exceptions in Rust. lines() expects the BufReader to be valid UTF-8, because if it's not, splitting it up into lines is not well-defined. lines() also returns `String`s, which must be UTF-8 in Rust. If you want a different encoding, use byte arrays. Same as in Python 3. If invalid UTF-8 is encountered, the iterator returns a None.

>let a = *registers.get(c[4]).unwrap_or(&0);

No exceptions. get returns an `Option` which either contains a reference to an i32 or is None if no such element is found. If it is None, we can continue to work with the default value 0.

>let b = c[6].parse::<i32>().unwrap();

>let d = c[2].parse::<i32>().unwrap();

Again, no exceptions. parse gives an `Option` which contains the result, an i32, or None.

>println!("Part 1: {}", registers.values().max().unwrap());

max only makes sense if the iterator it is called on yields at least one element. If it doesn't, there's an error. To return an error, an `Option` is used.


 No.834581

>>834578

<No exceptions? This sucks!

Languages that do have exceptions basically do the same except they return what would be called a Result<T, E> (T is the type of the return value and E is the type of an exception) in Rust, and automatically unwrap() the T if there is one, or pass the E up the stack until it is caught.


 No.834587

>>834564

Also

>favoring lambdas and dict lookups over my sick `if match`


 No.834597>>834687

macro_rules! cmp {
(($op:expr, $l:expr, $r:expr), ($($cmp:tt),*)) => {
match $op {
$(stringify!($cmp) => { $l $cmp $r })*
_ => { unreachable!() }
}
}
}

fn main() {
let instant = std::time::Instant::now();
let mut registers = std::collections::HashMap::new();
let mut b = 0;

for l in INPUT.lines() {
let mut iter = l.split_whitespace();

macro_rules! parse {
($iter:ident) => {(
$iter.next().unwrap(),
$iter.next().unwrap(),
$iter.next().unwrap().parse::<i32>().unwrap()
)}
}

let (l1, op1, r1) = parse!(iter);
iter.next();
let (l2, op2, r2) = parse!(iter);
let l2 = *registers.entry(l2).or_insert(0);

if cmp!((op2, l2, r2), (<, <=, >, >=, ==, !=)) {
let l1 = registers.entry(l1).or_insert(0);

match op1 {
"inc" => { *l1 += r1; }
"dec" => { *l1 -= r1; }
_ => { unreachable!() }
}

b = std::cmp::max(b, *l1);
}
}

let a = registers.values().max().unwrap();

let d = instant.elapsed();
println!(
"Part 1: {}\nPart 2: {}\nTime: {} ms",
a,
b,
(d.as_secs() as f64 + d.subsec_nanos() as f64 / 1000000000.0) * 1000.0
);
}

Now that is some breathtakingly beautiful Rust code. macros_rule! tbh


 No.834602

day 8 was fun. ocaml:

type modop = Inc | Dec
type condop = Gt | Ge | Eq | Ne | Lt | Le
type cond = If of (string * condop * int)

let input8 = [
"ba", Dec, 37, If ("znx", Ne, 0);
"zrn", Inc, -344, If ("znx", Gt, -9);
...
]

let day8 input =
let highest = ref 0 in
let registers = Hashtbl.create 100 in
let get reg = match Hashtbl.find_opt registers reg with None -> 0 | Some r -> r in
let put reg n =
if n > !highest then highest := n;
Hashtbl.replace registers reg n in
let inc reg n = put reg (get reg + n) in
let dec reg n = put reg (get reg - n) in
let alter op reg n = match op with Inc -> inc reg n | Dec -> dec reg n in
let check reg cond n =
(match cond with
| Gt -> (get reg) > n
| Ge -> (get reg) >= n
| Eq -> (get reg) = n
| Ne -> (get reg) <> n
| Le -> (get reg) <= n
| Lt -> (get reg) < n) in
let rec loop list =
match list with
| [] ->
let (reg, v) = Hashtbl.fold (fun k v (acc_k, acc_v) ->
if v > acc_v then (k, v) else (acc_k, acc_v))
registers ("fake", min_int) in
(reg, v, !highest)
| (reg1, op, n, If (reg2, cond, v)) :: rest ->
if check reg2 cond v then alter op reg1 n;
loop rest
in loop input


 No.834603

>>834571

pic related indeed

https://ocaml.org/learn/tutorials/garbage_collection.html

read it from top to bottom.


 No.834687>>834688

File (hide): 7110c4cf53197f7⋯.png (429.1 KB, 619x706, 619:706, 1488340010295.png) (h) (u)

>>834597

>unwrap

>beautiful


 No.834688>>834690 >>834699

>>834687

>hurr durr

>XDDDDDD

not an argument


 No.834690>>834691

File (hide): 5e63650e674a094⋯.jpeg (53.82 KB, 492x492, 1:1, 1458695310037.jpeg) (h) (u)

>>834688

No need to be so rusty friendo


 No.834691>>834692 >>834705

File (hide): 50c8c4e6883ee05⋯.jpg (95.47 KB, 900x888, 75:74, retard.jpg) (h) (u)


 No.834692

File (hide): 41832e8bd9d7df3⋯.jpg (4.32 KB, 250x164, 125:82, 1404860954446s.jpg) (h) (u)

>>834691

>rust is being discussed

>link python


 No.834699>>834703 >>834707

>>834688

how is unwrap better than

#define CHECK(expr)       \
if ((expr)) { \
perror(__func__); \
abort(); \
} //

#define CHECK_NULL(x) CHECK(!(x))
#define CHECK_NZERO(x) CHECK((x))
#define CHECK_LTZERO(x) CHECK((x) < 0)

// ...

FILE *f;
CHECK_NULL(f = fopen("dicks.jpg", "r"));

// ...

int sock;
CHECK_NZERO(getaddrinfo(...));

// ...

CHECK_LTZERO(sock = socket(domain, type, protocol));
CHECK_LTZERO(connect(sock, "8ch.net", 7));
?

Actually, I can kinda see the point of .unwrap() (fixes the butt-ugly inconsistency of stdlib return values, one function for checking), but why not just unwrap in the first place? Why can't you say

let f = File::open?("dicks")
or something? (notice the ?)

Would Rustfagsdevs consider adding ? functions for returning an Option and exploding by default?


 No.834703

>>834699

>Would Rustfagsdevs consider adding ? functions for returning an Option and exploding by default?

Added in v1.22

https://blog.rust-lang.org/2017/11/22/Rust-1.22.html

>The headline feature for this release is one many have been anticipating for a long time: you can now use ? with Option<T>! About a year ago, in Rust 1.13, we introduced the ? operator for working with Result<T, E>. Ever since then, there’s been discussion about how far ? should go: should it stay only for results? Should it be user-extensible? Should it be usable with Option<T>?

But that only works if the function returns an Option. The main function doesn't return anything so you can't do it there. There is something in the works to address this though.


 No.834705>>834732 >>834740

>>834691

>turkroach

>implying I'd post smug anime

This is your brain on delusion.


 No.834707>>834710

>>834699

also File::open returns a Result not an Option


 No.834710>>834712

>>834707

What I was trying to say is, if you want to check errors yourself, you should be able to do

let f = File::open?("dicks").unwrap()
(which is the current behavior) but if you want the stdlib to crash the program you should be able to just do
let f = File::open("dicks")
.


 No.834712>>834714 >>834752

>>834710

that is absolutely awful though. why would you want to crash your program?


 No.834714>>834716

>>834712

Isn't the entire point of .unwrap() crashing your program if the value is None? The second statement should have an implicit unwrap was what I was saying.


 No.834716>>834770

>>834714

But you only use unwrap when you don't want to do propert error handling or when you are sure that it is Some/Ok.

You propose to implicitly (Rust is all about being explicit btw) panic. But in most real world cases you don't want that.


 No.834721>>834764

>be anti rust shill

>hurr muh unwrap

>see this:

https://play.rust-lang.org/?gist=4f59385d7ea3cae44be11499cd1c25d2

>ctrl + f unwrap

>0 matches

>kill self


 No.834732

File (hide): dd5b0047203f414⋯.jpg (83.94 KB, 500x370, 50:37, 1458404724050.jpg) (h) (u)


 No.834740>>834760

>>834705

fuck off kampfy


 No.834752>>834755

>>834712

>why would you want to crash your program

go away from programming until it's too late.

people like you created fucking PHP and Javascript.


 No.834755

>>834752

>go away from programming until it's too late.

so after it is too late i can come back?

LOL. learn 2 english, kiddo.


 No.834760

>>834740

>i am now imkampfy

ok


 No.834764

>>834721

>replace .unwrap() with Result op* which unwraps anyway

>replace .unwrap() with .ok()

wow you sure convinced me


 No.834770>>834825

>>834716

>But you only use unwrap when you don't want to do propert error handling or when you are sure that it is Some/Ok.

Well, you wouldn't use it where you don't have Some. If you can keep which calls need a .unwrap() in your head, you can most likely keep which calls need a ?.

>(Rust is all about being explicit btw)

explicity != verbosity. Rust is verbose. If I wanted the option to do error checking myself I could just use File::open?(name) and get an Option. This is being explicit. Requiring .unwrap() on every call that returns Some/Ok is being verbose.


 No.834825>>834827

>>834770

>explicity != verbosity. Rust is verbose. If I wanted the option to do error checking myself I could just use File::open?(name) and get an Option. This is being explicit. Requiring .unwrap() on every call that returns Some/Ok is being verbose.

Error handling in Rust is explicit. You can't ignore the possibility of an error like you could in languages that have unchecked exceptions or C. This may be verbose, but it most definitely is explicit.

You don't have to use unwrap, in fact it is discouraged to do that in real world code.

Also you are literally arguing in favor of having implicit error handling by default.


 No.834827>>834839

>>834825

>in fact it is discouraged to do that in real world code.

they why does every rust code in this thread have copious amounts of unwrap in it?


 No.834839

>>834827

because it isnt real world code? because as long as the input isnt bad it wont panic? because even if it panics nobody cares?


 No.834979>>834982 >>835014

>>834463

day 9. still easy enough.

void stream_processing(string_view input)
{
size_t level = 0, score = 0, garbage_count = 0;
not_garbage:
for (; !input.empty(); input.remove_prefix(1))
if (input[0] == '{') score += ++level;
else if (input[0] == '}') --level;
else if (input[0] == '<') goto garbage;
goto epilogue;
garbage:
for (input.remove_prefix(1); !input.empty(); input.remove_prefix(1))
if (input[0] == '!') input.remove_prefix(1);
else if (input[0] == '>') goto not_garbage;
else ++garbage_count;
epilogue:
cout << "part 1: " << score << '\n';
cout << "part 2: " << garbage_count << '\n';
}


 No.834982

>>834979

I should probably add an "input.remove_prefix(1);" before the "goto not_garbage;" to save an iteration of the first loop. Meh, not a big deal.


 No.834985>>835052

183 characters

too lazy to golf it further, I think it must be possible but fuck it.


import re
t=re.sub('!.','',open('i','r').read())
g=re.compile('<.*?>')
s=0
l=0
for c in g.sub('',t):
if c=='{':l+=1
elif c=='}':s+=l;l-=1
print(s,sum(len(x)-2for x in g.findall(t)))


 No.835011

another fun day, though a bit easy. ocaml:

open Printf                                                                                   

let clean s =
let len = String.length s in
let scores = ref 0 in
let gc = ref 0 in
let rec garbage i cb =
match s.[i] with
| '!' -> garbage (i + 2) cb
| '>' -> cb (i + 1)
| c -> (gc := !gc + 1; garbage (i + 1) cb)
and group i parens score =
match s.[i] with
| '!' -> group (i + 2) parens score
| '<' -> garbage (i + 1) (fun i -> group i parens score)
| '{' -> group (i + 1) (parens + 1) (score + parens + 1)
| '}' -> if parens = 1 then (scores := !scores + score; loop (i + 1)) else
group (i + 1) (parens - 1) score
| c -> group (i + 1) parens score
and loop i =
if i = len then !scores, !gc else
match s.[i] with
| '!' -> loop (i + 2)
| '<' -> garbage (i + 1) (fun i -> loop i)
| '{' -> group (i + 1) 1 1
| c -> failwith (sprintf "unexpected character in loop %d: %c" i c)
in loop 0


 No.835014>>835023

>>834979

>goto

>not mutually recursive functions

damn, I missed that ! only shows up in garbage


 No.835023

>>835014

>mutually recursive functions

Wouldn't have looked much better. Also, I don't know if GCC would have been able to optimize it into something as efficient.


 No.835037>>835067

File (hide): 3b54ab720ddb170⋯.jpg (27.2 KB, 418x396, 19:18, 1245692698.jpg) (h) (u)

More hard challenges will be released on the

12th

18th

25th

respectively.

The other days are normal/easy challenges.


 No.835046

File (hide): 7879fd276a220e3⋯.png (88.8 KB, 1282x634, 641:317, day9.png) (h) (u)


 No.835052>>835056

>>834985

Good job.

Why has this thread been silently anchored? Does code trigger /tech/?


 No.835056>>835058

>>835052

>silently anchored

>>>/g/

The bumplimit is 400 posts. Make a new thread.


 No.835058

>>835056

> bumplimit is 400 posts

Ahh. We might as well keep this thread until full.


 No.835061>>835065 >>835081

Wtf this shit is too easy: https://play.rust-lang.org/?gist=0720b3a232a28b8e524ae589300745f7

fn main() {
let mut iter = INPUT.iter();
let mut garbage = false;
let mut group = 0;

let mut solution_part1 = 0;
let mut solution_part2 = 0;

while let Some(&b) = iter.next() {
match b {
b'>' => { garbage = false; }
b'!' => { iter.next(); }
b'<' if !garbage => { garbage = true; }
b'{' if !garbage => { group += 1; solution_part1 += group; }
b'}' if !garbage => { group -= 1; }
_ if garbage => { solution_part2 += 1; }
_ => {}
}
}
}


 No.835065

>>835061

Nice work.


 No.835067

>>835037

source?


 No.835081

>>835061

ocaml in (almost) the style of your rust:

let clean2 s =
let len = String.length s in
let i = ref 0 in let b = ref ' ' in
let iter_next () = if !i = len then false else (b := s.[!i]; incr i; true) in
let garbage = ref false in
let group = ref 0 in
let answer1 = ref 0 in
let answer2 = ref 0 in

while iter_next () do
match !garbage, !b with
| _, '>' -> garbage := false
| _, '!' -> ignore (iter_next ())
| false, '<' -> garbage := true
| false, '{' -> incr group; answer1 := !answer1 + !group
| false, '}' -> decr group
| true, _ -> incr answer2
| _, _ -> ()
done;
(!answer1, !answer2)
with the bytecode compiler it's nearly half the speed of my solution above; with ocamlopt it's marginally faster:
$ ./day9
mine 10000 iterations: 0.000058 s
rust 10000 iterations: 0.000057 s

$ ./day9
mine 10000 iterations: 0.000058 s
rust 10000 iterations: 0.000056 s

$ ./day9
mine 10000 iterations: 0.000063 s
rust 10000 iterations: 0.000056 s

$ ./day9.byte
mine 10000 iterations: 0.000251 s
rust 10000 iterations: 0.000491 s
the timing is the real timing / iterations ofc.


 No.835167>>835180

How many of you guys actually log into the site?


 No.835180

>>835167

you have to log into it to get the puzzles. IIRC I just used a github throwaway.


 No.835307

New thread: >>835306

New thread: >>835306

New thread: >>835306

New thread: >>835306




[Return][Go to top][Catalog][Screencap][Nerve Center][Cancer][Update] ( Scroll to new posts) ( Auto) 4
429 replies | 51 images | Page ???
[Post a Reply]
[ / / / / / / / / / / / / / ] [ dir / 1917 / arda / cafechan / flutter / had / kocsog / leftpol / senran ][ watchlist ]