Elijah Nguyen

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.

Dylan Lopez

Day 1 in Rust: 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>() );}`

Michael Ward

`#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;}`

Asher James

[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]

Jason Butler

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()}`

Landon Hughes

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

Joshua Howard

`#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;}`

`#!/usr/bin/python3for 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)))`

Gabriel King

`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")))`

Austin Perry

`\$_=<>;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".\$/`

Julian Morgan

`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}'`

Andrew Nguyen

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

Juan Bell

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

Jackson Collins

Solving these is an option to kill your boredom in this shithole
thats what shitpostings for cunt

James Wood

MUUUUUH (((BOTNET)))
have you considered killing yourself?

Cameron Gomez

Shut up and code.

Ayden Young

My thoughts exactly...

Ethan Lee

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);`

Matthew Brooks

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

Carter Price

ITT faggots try to broadcast their Holla Forums 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.

Jordan Bennett

`\$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.\$".\$/`

Michael Morales

spd-say -t child_female -p +100 faggot

Benjamin Murphy

Mathematica

Hunter Gomez

Lighten up mate, these are only for fun.

Jaxon Allen

maintainable code
for a Christmas challenge
who cares, faggot

Ethan Young

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?

Xavier Harris

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

Asher Young

Here's something to soothe your gay rage

Leo Lopez

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";`

Luis Sanders

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";`

Caleb Brown

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; });} `

Ryder White

this

Angel Wright

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!"

Aaron Watson

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.

Cooper Jackson

this is what /g/tards actually believe

Brayden Ramirez

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`

Landon Morgan

ocaml or some shit
no pattern matching
pajeet

Leo Powell

get a throwaway github. it's the best of the bunch.
they fired the safe-space tranny for persistently making real girls uncomfortable

Ryder Baker

not an argument

James Nelson

github
\$7 silver shekels a month
"""""""the best""""""""
not bitbucket
unlimited free private suppositories

Xavier Evans

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

Luke Lewis

You have to pay a monthly fee for private repos.

Liam Ortiz

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, user.

Luke Barnes

Yeah but otherwise it's free.

James Barnes

I hope this is more to your taste, user.`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`

Elijah Sullivan

you have to pay for a private profile
"it's free"

Parker Jackson

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

Aiden Johnson

it annoys me that this piece of shit rewrite is actually better for not producing bullshit answers:`utop # adv_faggotry "hi there";;- : int = 112utop # use_of_toilet "hi there";;Exception: (Failure "non-digit found in string").Raised at file "pervasives.ml", line 32, characters 22-33Called from file "puzzle.ml", line 44, characters 25-36Called from file "toplevel/toploop.ml", line 180, characters 17-56`

Angel Robinson

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.

Elijah Edwards

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

Jackson Russell

watching tv

Julian Taylor

<not watching television

Owen Cooper

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...

Lincoln Thompson

awarding (((yellow stars))) to people
oy vey!

Robert Parker

Day 2 is up.

Xavier Turner

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.

Asher Roberts

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)

Aiden Morales

there are A LOT of chinks on the leaderboard

Joseph Wright

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.

Ayden Murphy

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

Joseph Martinez

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.

Jaxson Howard

bully me
POST IT!

Angel Moore

I ugh, don't have an account.

Dominic Turner

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

Ryder Bailey

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.

Oliver Torres

totally defeats the point of rushing then imo

Bentley Young

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

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.

Carson Taylor

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

Jose Hall

I take that back, my part1 is marginally faster.

I haven't seen anyone using Ada yet.

Austin Torres

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.

Blake Lopez

`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>());}`

Luis Sanchez

I don't think the input size necessitates threading user

Nicholas Wright

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

Wyatt Morales

Could someone please screenshot part 2?

Evan Watson

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'

Wyatt Moore

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

Henry Richardson

no code
spotted the butthurt LARPer

Mason Fisher

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

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>());}`

Asher Morris

Christopher Jackson

Day 2: play.rust-lang.org/?gist=bd3baf7bd840dc8a241644b9a02c2e08&version=stable
Time: 0.034 ms

Josiah Bennett

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`

Daniel Brown

that's run as: sudo perf stat -e cycles -e instructions ./p
I don't use perf much, just copying someone who uses it

Charles Bell

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.

Parker Miller

There is no hard requirement on performance you LARPfag.

Charles Lewis

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!

John Rivera

Are you just pretending to be retarded?

Noah Howard

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

le smug aniuuuuh
shit. you won. i am sooooooo mad now.

Jason Barnes

he just doesn't want to compare rust against ocaml for no reason
meanwhile:`\$ time python -c 'print 1'1real 0m0.039suser 0m0.023ssys 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.

Ryan Ortiz

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.

Carson Johnson

muh hard requirement
Please quote me where i said that.
rustfag
Found the triggered anti Rust shill. Post code or kill yourself.

John Ortiz

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.

Chase Torres

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.

Isaac Flores

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.

Joshua Peterson

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.

Zachary Bennett

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.

Luke Foster

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.

Zachary Powell

content-type : text/plain
No I receive my input over HTTP.

Josiah Turner

fucking hell this autism

Henry Cox

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

Ayden Rivera

`\$*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`

Alexander Hall

Removed indexing: play.rust-lang.org/?gist=c37b9b8247652a8df7dd95eb194d71ac

Camden Kelly

Horrifying indeed. What language is this?

Bentley Ross

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

Isaiah Allen

yes, it's perl6.

Joshua Jackson

Does it still have worse performance than perl5?

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.

Nicholas Campbell

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`

It's slow as shit

Jayden Cox

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 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.

Benjamin Hughes

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.

Angel Kelly

perl6.party/post/On-Troll-Hugging-Hole-Digging-and-Improving-Open-Source-Communities
pugs.blogs.com/audrey/2009/08/my-hobby-troll-hugging.html
Audrey Tang, now Taiwan's Minister of Digital
So what's the most cucked language now, HUH?

Ayden Perry

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

Benjamin Thomas

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

Jordan Murphy

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

Levi Murphy

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!

Eli Walker

Learn J or K.

Dominic Wood

`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)))))`

Elijah Lewis

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())`

Noah Hernandez

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`

Carter Morgan

Now do it in a real language (like C)

Nicholas Morgan

KEI worked on it
Jsoftware likes you
more APL-like in a bad way
Roger's gone, working for APL company now. deadlang?
good syntax
lot of good design
open-source implementations [because Kx hates you and hid away their version after it caught popularity]
Kx hates you fucking LARPers. Go jump off a bridge, nerd
no KEI, no J labs, no books, impoverished red-headed stepchild lang

Hudson Stewart

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.

James Cox

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;}`

Jacob Lee

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;}`

Jason Green

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 ()) mlet 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 1let 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) 0let 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 0let spy_found = ref falselet looking_for n = spy_found := false; spy_target := nlet 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 sumlet 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)`

Colton Collins

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

Hudson Mitchell

semicolons
????????

Parker Roberts

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); } }}`

Dylan Flores

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?

Alexander Hill

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

Jayden Smith

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.

Juan Davis

e.g. rustfag:
It was also kind of unfortunate that my solution for the first part was completely useless for the second part.

Eli Kelly

I'm not proud. 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();}`

Levi Baker

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

Luis Brown

Question about the day1 challenge partA
What should this testcase return?
9919999

Jaxon Jones

45

Camden Wood

just change the input here:

Justin Flores

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

well they are wrong

Dylan Ramirez

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

Logan Perry
Isaac Sullivan

is there an Holla Forums private leaderboard yet?

Joshua Jenkins

ocaml's fine though:`utop # sum_faggotry "9919999";;- : int = 45utop # sum_matching 9919999;;- : int = 45`

Sebastian Clark

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.

Isaiah Flores

But the versions in and do and they give the correct output, see seems to wrap too.

Bentley Clark

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.
play.rust-lang.org/?gist=2092de6b3ca8df308960c83b7073b7c5
Time: 0.04 ms

Carson King

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

Jaxon Garcia

what..?

Mason Smith

nodev LARPer spotted
antisage btw

Jonathan Long

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

Luis Jenkins

45 #MeToo

Nathan Sullivan

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

Brandon Barnes

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.

Ryan Cruz

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.

Bentley Howard

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

Michael Clark

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

Jaxson Gray

it could be useful in code golf though

Landon Brooks

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.

code golf though
Of course.

Levi Moore

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- oeis.org/A141481/b141481.txt | grep -v "^#" | cut -f2 -d' '`; do if [ \$row -gt \$INPUT ]; then echo \$row; break; fi; done

Ryder Wilson

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

Christopher Ortiz

forgot that it's mathematica
Stallman does not approve it

Jeremiah Perry

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

Carson Ramirez

Here is your goldstar, you earned it champ

Jonathan Thompson

c++ was a mistake

Samuel Rogers

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.

Charles Scott

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;}`

Blake Bell

(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; alet 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.

Jason Taylor

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.

Alexander Robinson

too much typing

`import rews = 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 = 0for l in lines: l = tuple(map(lambda x: ''.join(x), map(sorted, l))) h = set(l) if len(h) == len(l): i += 1print(i)`

Ethan Johnson

the leaderboard system is designed to suck.
just collect your yellow stars m8

Juan Torres

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

Charles Ramirez

excuses

Michael Ortiz

well, then day 4 should have been harder than 3.
maybe it's just one error, I dunno.

Anthony Wood

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.

Levi Rogers

optimization is not needed here though
and when it's needed, Rust > Haskell :)

Caleb Parker

... 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".

Dominic Evans

Haskell, from reddit`valid pass = length (nub \$ sort pass) == length passmain = 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.

Charles Jackson

Here's someone doing it with Core (alternate stdlib for OCaml):`open Corelet all_unique_words words = let set = String.Set.of_list words in String.Set.length set = List.length wordslet sort_chars word = String.to_list word |> List.sort ~cmp:Char.compare |> String.of_char_listlet sort_words words = List.map words ~f:sort_charslet no_anagrams = Fn.compose all_unique_words sort_wordslet 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";`

Hudson Richardson

Mathematica makes short work of it.

Elijah Lewis

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

Leo Miller

oh yeah, it's the point-less style

Asher Cook

fug, of course it's somethingML.
they look very similar when I haven't written in neither of them for a year.

Austin Murphy

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);`

Nolan Reed

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

Isaac Gray

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.

Zachary James

`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 );}`
play.rust-lang.org/?gist=6380b10c0b0ec10a0b742507b050ca92
Time: 0.52 ms

Aaron Hughes

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.

Jonathan Ramirez

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
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"

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

Nolan Reed

That's hilarious.

Nicholas Bennett

Thanks for the code review.

Christian Johnson

nub
O(n^2)

Gavin Rogers

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)))))`

Julian Roberts

I optimized it: play.rust-lang.org/?gist=e036c920b0c5bc7bfec445cabf2473f9
Time: 0.3 ms
Suck it faggots! Rust is literally the fastest and safest language.

Ryder Anderson

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.

Luke Jenkins

hash with no collision strategy
It uses linear probing though

Carter Perez

oh. yeah I see it now.

Justin Hernandez

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 <- 0endlet hash_asis = Hashtbl.hashlet 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 alet () = 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\$ ./riioPart 1: 337Part 2: 231Time: 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)

Kayden Parker

that syntax highlighting
no serious language uses ' for strings

Nathaniel Allen

why is it not faster orz
Because Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.

Ayden Garcia

allaha huakbar

Jose Jackson
Daniel Jones

#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'.

Charles Richardson

citing the shootout
in CY+2
on this real world toy problem OCaml and Rust both take no time. That's fine with me.

Charles Phillips

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

Angel Mitchell

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.

Gavin Collins

my laptop can't digitize people.
irrelevant
I didn't actually compare rust against ocaml directly?
wrong: > 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?

Alexander Foster

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()`

Nicholas Lewis

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

What are you trying to do here?

Sebastian Davis

in the problem the last number per layer will always be an odd number squared
`17 16 15 14 1318 5 4 3 1219 6 1 2 1120 7 8 9 1021 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.

Aaron Howard

i guess i should say shell not layer

Michael Lee

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: 337part 2: 231Time: 0.000000 s`

Jace Hill

Very noice.

Grayson Murphy

check em'

Asher Wood

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()) `

Christian Wood

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;}`

Xavier Diaz

you only have 1 ms for each challenge
really?
how would they check that?

Gabriel Ortiz

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.

Cameron Wright

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 0let 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 startlet 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.

Charles Cruz

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

Wyatt Wright

Joshua White

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

Nathaniel Gonzalez

`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}`
play.rust-lang.org/?gist=c48827dcbf01fb0efa5acbfe7442303e
Time: 83 ms
I fucking blew it. I ruined Christmas.

Luke Baker

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

Cooper Ross

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!

Jayden Hernandez

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

Matthew Anderson

Pretty substantial drop off from day 2 to 3.

Ryan Rogers

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

Christopher Cooper

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

Day 5 in Rust: 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()));}`

Christian Thomas

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

Noah Fisher

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}`

Nathan Gomez

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?

Justin Bell

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

Brayden Cooper

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__0301-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__0301-3`

Camden Lewis

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 < input23948711real 1m40.691suser 1m40.647ssys 0m0.037s`
Compared to my Rust version thats pretty much the one Steve Klabnik posted:
`~ \$ time ./dik < input23948711real 0m0.054suser 0m0.051ssys 0m0.003s`
Perl6 truly is the future of computing.

Anthony Green

`[email protected]_,\$_ while<>;\$i+=\$_[\$i]>=3?\$_[\$i]--:\$_[\$i]++while\$i<~~@_&&++\$a;print\$a.\$/`
`~ \$ time perl dik.pl < input 23948711real 3.35suser 3.34ssys 0.00s`

Nolan Williams

rip perl6, we hardly knew ya

Joseph Martinez

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.

Aiden Ramirez

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

Christopher Baker

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

Robert Allen

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

Cameron Peterson

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

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.

Alexander Long

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.

Landon Brown

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

David Lee

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?

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.

Asher Sanchez

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)))`

Parker Parker

What language is this?

Ayden Allen

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];}`

Just good old C++.

Mason Mitchell

are you retarded

Colton Collins

wtf does part 2 of day 6 even mean?

Brandon Wright

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

Dominic Walker

close, but not exactly

Wyatt Brooks

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"

Juan Lewis

`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) blockslet 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; !maxilet 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

Anthony Rivera

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)))))`

James Russell

Day 6 (cleaned up a bit)

Parker Fisher

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?

Aiden Torres

nevermind, I misunderstood the question

Easton Bailey

Day 6 in Rust: 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().

Jack Bailey

rustbyexample.com/primitives/array.html uses .len() on a literal array

Matthew Lopez

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.

Nathaniel Bell

Like this:
`const arr: [u32; 3] = [1,2,3];fn test(x: [u32; arr.len()]) { println!("{:?}", x);}fn main() { test(arr);}`

Elijah Bennett

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; !maxilet 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`

Angel Perez

naturally the author posted it with a sincere apology. that community is fucked`import Data.Sequence (Seq)import qualified Data.Sequence as Seqimport Data.Set (Set)import qualified Data.Set as Setimport Data.Listdistribute :: Int -> Int -> Seq Int -> Seq Intdistribute 0 _ banks = banksdistribute remaining currentIndex banks = distribute newRemaining newIndex newBanks where newRemaining = remaining - 1 newIndex = mod (currentIndex + 1) (length banks) newBanks = Seq.adjust (+1) currentIndex banksdoCycle :: Seq Int -> Seq IntdoCycle 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 banksgetFirstRepeatedConfig :: 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 prevConfigsgetTimeToCycle :: Int -> Seq Int -> Seq Int -> IntgetTimeToCycle count banks targetConfig | banks == targetConfig = count | otherwise = getTimeToCycle newCount newBanks targetConfig where newCount = count + 1 newBanks = doCycle banksmain :: 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)`

Henry Martinez

(((functional programming)))

Ayden Jenkins

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

Eli Cruz

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.

Nicholas Sanchez

You don't need to????

Jason Butler

I want to!

Hudson Sanchez

John Clark

/reddit/index.html

Gabriel James

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.

Blake Cook

binary tree
too slow
SIMD
llvm already does that for me

Ethan Baker

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.

David Cox

FUUUUUUUUUUCK! Christmas is ruined again.
play.rust-lang.org/?gist=1c21581122ca98fc2b342dd0a989ca98&version=nightly&mode=release
Time: 1.15 ms

Cooper Long

Hmm if I run it 1000 times and take the average time it is <1ms. I'll take. Christmas is saved!!!
play.rust-lang.org/?gist=a20ae380e856126347b419f65743373f&version=nightly&mode=release
Time: 0.9 ms

Ryder Edwards

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.

John Nguyen

Every day except 5 runs under 1ms. Day 5 takes 83 ms: 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.

James Howard

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

Wyatt Bell

`/** * 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 <gnu.org/licenses/>. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>struct pos { int item, index;};voidprint_banks(int *banks, int blen) { printf("["); for (int i = 0; i < blen; i++) printf("%d, ", banks[i]); printf("\b\b] \n");}intnext_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;}voidpush_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;}voidpush_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;}intsteps_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 pospop_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};}intmain(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;}`
`[email protected]:~\$ gcc -o day6 day6.c -O3 -ffast-math -funroll-loops -ftree-vectorize -Wall -Wextra -Werror -pedantic -std=c99[email protected]:~\$ time ./day6 1 < day6input >/dev/nullTotal steps: 4074real 0m0.044suser 0m0.041ssys 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.

Jackson Taylor

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?

Anthony James

verbose?
It's perfectly normal C.
Stylistically, C is all downhill from here, especially as it's ported.

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.

128 bytes
Brain melt, i meant 16 ints.

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

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.

Isaiah Morris

polite bump

Dominic Bailey

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.

Colton Gomez

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.
And?

Andrew Stewart

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.

Aiden Thompson

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.
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.

Samuel Thompson

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;}`

Ian Robinson

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.

Joshua Nguyen

On my machine:
Part 1: 12841
Part 2: 8038
Time: 2553 us
But yeah it's not optimal. With the input from 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.

Blake Nelson

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.

Samuel Gutierrez

binary tree
You could try a bloom filter.

Brayden Nelson

Finally day 7 required a bit of thinking to get through.
Still, it's mostly brute force.

`import refrom collections import defaultdictpt = 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, otherall = set()not_bottom = set()class P: def __init__(self): self.name = None self.weight = None self.parent = None self.children = Noneall_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 + diffprint(check_weight(root))`

Aiden Ramirez

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.

Hudson Reed

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); }`

Evan Green

wow
is it C++18? or what version?
last time I saw any C++ code it didn't look like that.

Parker Jackson

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 = 370utop # 274 * 3 + 370;;- : int = 1192utop # 1184 - 274 * 3;;- : int = 362`

Ryder Martinez

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: (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.

Luke Evans

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++?

Sebastian Williams

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.

Justin Martin

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 , I'm using a type trait in one place, but that's it. If you mean without any of 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.

Gavin Taylor

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)

Benjamin Cooper

`#!/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 <gnu.org/licenses/>.import sysimport reimport collectionsclass 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)))`
`[email protected]:~\$ time python3 day7.py <day7input >/dev/nullreal 0m0.095suser 0m0.072ssys 0m0.008s`
C version coming after the Py3 implementation.

Carter Martinez

Pajeets having trouble traversing a tree

Ryan Ramirez

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

Carter Cooper

`/** * 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 <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;}intget_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

Jackson Russell

`voidresolve_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); }}intcalc_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;voidget_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); }}intpart2(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]; }}intmain(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;}`
`[email protected] ~ % time ./day7 1 < day7inputName of root: vvsvez./day7 1 < day7input 0.00s user 0.00s system 97% cpu 0.007 total[email protected] ~ % time ./day7 2 < day7inputRequired 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.

Matthew Stewart

Don't you know what a pastebin is?

Aaron Long

Jace Mitchell

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.

Lincoln Rodriguez

Do you want me to modify and study your comment?

Isaac Cooper

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

Kevin Butler

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

Justin Wilson

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
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

Juan Bennett

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; } }}`

Michael Watson

fuck the borrow checker
Isn't that Rust's greatest ally?

Noah Ortiz

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

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).

Xavier Torres

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

Hudson Howard

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.

Daniel James

coders
guys in the background clearly not doing coding
well done

Dylan Watson

guys in the background clearly not doing coding
But the guys in the front are.
Prove me wrong.

Kayden Lopez

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)); }}`

Elijah Ross

this is worse than c++

Matthew Long

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.

Liam Richardson

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.

Bentley Edwards

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

Liam White

Very memory-safe :^)
Yes because it just crashes if .unwrap() fails
Just use pointers, man.
No, that would be unsafe.

As if your neet time was worth anything

Luke Jenkins

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

Dylan Clark

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.

John Collins

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.

Zachary Clark

Cheating with eval

`import refrom collections import defaultdictws = 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 = 0with 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)`

Dylan Bell

Day 8 Golfed
203 characters

`import collections as Cv=C.defaultdict(int)m=0for 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)`

Michael Anderson

200 characters
ditched 'if' statement because I can implicitly convert bool to int
`import collections as Cv=C.defaultdict(int)m=0for 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)`

Jordan Campbell

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 == '-'; }`

Kayden Bennett

197 characters
no need to compare strings by equality here :D
`import collections as Cv=C.defaultdict(int)m=0for 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)`

Brayden Morris

`#!/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 <gnu.org/licenses/>.import sysdef 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.
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
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))
Cheating with eval
Cheating is for niggers.

Hunter Parker

tl;dr

Elijah Collins

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

Henry Anderson

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));}`

Blake Harris

Still longer than Python with 197 characters.

Alexander Sanders

I guess I can also replace the `ins == "inc"` with `ins[0] == 'i'`, while I'm at it.

Benjamin Collins

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

David Nelson

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

Joshua Roberts

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

Elijah King

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

Parker Nelson

Wtf I love Rust now 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));}`

Brayden Jenkins

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.

Benjamin Powell

Code golf is a legitimate thing btw.

Robert Walker

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

Wyatt Hernandez

And so is optimization tbh fam.

Hudson Allen

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);}`

Carter Turner

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

Jonathan Hughes

I said day 7

Oh right. No. Maybe Steve will.

Jackson Powell

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

Nathan Kelly

filter(lambda x: x, input.split('\n'))
Why don't you just input.splitlines()?

Zachary Harris

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"]`

Benjamin Perry

Day 7: 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: play.rust-lang.org/?gist=20bb760159cbd1ff5d5479c96f52c6e1
Time: 0.38 ms
Pretty verbose. I'm probably going to make it shorter later today.

`[email protected] ~ % grep unwrap day8.rs | wc -l13`

Justin Carter

muh LOC
LOL. >>834113
stfu you stupid turkoachh

Cameron Hernandez

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.

Parker Gray

`grep unwrap >>834487 | wc -l6`
So? Would you rather prefer undefined behavior?

Anthony Ramirez

stfu you stupid turkoachh
oachh
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.
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.

Jordan Hughes

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

Robert Thompson

oh look. a good thread on Holla Forums
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

Lucas Jones

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

Jace Diaz

shilling for some reddit "puzzle" crap
lmfao

Andrew Turner

reference counting
as i said: pajeet
polite sage. im going to stop engaging you now.

Leo Kelly

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 and started shitposting.

Angel Carter

pic related
Give one argument against it.

Jonathan Morgan

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.

Evan Gomez

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

Brody Ward

Rc<RefCell<…
lol

Jason Gray

Please see my updated solution in . 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.

Nathan Lee

<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.

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

Evan Johnson

`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

Lincoln James

day 8 was fun. ocaml:`type modop = Inc | Dectype condop = Gt | Ge | Eq | Ne | Lt | Letype 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`

Jackson Thomas

pic related indeed
ocaml.org/learn/tutorials/garbage_collection.html
read it from top to bottom.

Ethan Taylor

unwrap
beautiful

Bentley Moore

hurr durr
XDDDDDD
not an argument

Alexander Russell

No need to be so rusty friendo

Kevin Sanders

docs.python.org/3/library/exceptions.html#StopIteration
kill yourself turkroach

Connor Ward

rust is being discussed

Hunter Sullivan

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?

Jeremiah Collins

Would Rustfagsdevs consider adding ? functions for returning an Option and exploding by default?
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.

Luis Torres

turkroach
implying I'd post smug anime
This is your brain on delusion.

Michael Jackson

also File::open returns a Result not an Option

Levi Harris

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")`.

Asher Bell

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

Jaxon Morgan

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.

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.

Ethan Foster

be anti rust shill
hurr muh unwrap
see this:
play.rust-lang.org/?gist=4f59385d7ea3cae44be11499cd1c25d2
ctrl + f unwrap
0 matches
kill self

Kevin Young

fuck off kampfy

Leo Myers

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.

Owen Perry

go away from programming until it's too late.
so after it is too late i can come back?
LOL. learn 2 english, kiddo.

Benjamin Hall

i am now imkampfy
ok

Carter Scott

replace .unwrap() with Result op* which unwraps anyway
replace .unwrap() with .ok()
wow you sure convinced me

Lincoln Powell

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.

Christian Jones

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.

Christopher Martinez

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?

Alexander Cook

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

Asher Miller

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';}`

Hunter Smith

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.

Parker Garcia

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

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

Ryder Kelly

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`

Ayden King

goto
not mutually recursive functions
damn, I missed that ! only shows up in garbage

Liam Lopez

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.

Evan Nguyen

More hard challenges will be released on the
12th
18th
25th
respectively.
The other days are normal/easy challenges.

Joshua Hughes

Good job.

Why has this thread been silently anchored? Does code trigger Holla Forums?

Sebastian Williams

silently anchored
/g/index.html
The bumplimit is 400 posts. Make a new thread.

Julian Turner

bumplimit is 400 posts
Ahh. We might as well keep this thread until full.

Liam Martinez

Wtf this shit is too easy: 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; } _ => {} } }}`

Henry Sanchez

Nice work.

James Wright

source?

Luke Gomez

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:`\$ ./day9mine 10000 iterations: 0.000058 srust 10000 iterations: 0.000057 s\$ ./day9mine 10000 iterations: 0.000058 srust 10000 iterations: 0.000056 s\$ ./day9mine 10000 iterations: 0.000063 srust 10000 iterations: 0.000056 s\$ ./day9.byte mine 10000 iterations: 0.000251 srust 10000 iterations: 0.000491 s`the timing is the real timing / iterations ofc.

Isaiah Cox