Advent of Code 2017

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

adventofcode.com/

Other urls found in this thread:

play.rust-lang.org/?gist=b369f967792ec62e7eb875201ff0a278&version=stable
codepad.org/CiFpQwfb
codepad.org/gyUmadgj
codepad.org/LPJ86RtI
codepad.org/cBpouX3o
reddit.com/r/adventofcode/comments/7h0rnm/2017_day_2_solutions/dqn9gd9/
reddit.com/r/adventofcode/comments/7h0rnm/2017_day_2_solutions/dqn9mju/
play.rust-lang.org/?gist=a66c52c2c097b90b9aa02b2e5b2e8b20&version=stable
play.rust-lang.org/?gist=62a11d20dbdcdb8e26e66efd08f0a340&version=stable
play.rust-lang.org/?gist=bd3baf7bd840dc8a241644b9a02c2e08&version=stable
play.rust-lang.org/?gist=4628d63c3e21ea1cc42f847ced908dfc
play.rust-lang.org/?gist=c37b9b8247652a8df7dd95eb194d71ac
perl6.org/:
perl6.party/post/On-Troll-Hugging-Hole-Digging-and-Improving-Open-Source-Communities
pugs.blogs.com/audrey/2009/08/my-hobby-troll-hugging.html
play.rust-lang.org/?gist=e075c3521573c8c2c36d8316f0b096e6&version=stable
codepad.org/ONnL9NnO
codepad.org/UzRjUfXs
play.rust-lang.org/?gist=2092de6b3ca8df308960c83b7073b7c5
oeis.org/A141481/b141481.txt
reddit.com/r/adventofcode/comments/7hf5xb/2017_day_4_solutions/dqqjj88/
play.rust-lang.org/?gist=6380b10c0b0ec10a0b742507b050ca92
play.rust-lang.org/?gist=e036c920b0c5bc7bfec445cabf2473f9
benchmarksgame.alioth.debian.org/u64q/compare.php?lang=ocaml&lang2=rust
play.rust-lang.org/?gist=c48827dcbf01fb0efa5acbfe7442303e
play.rust-lang.org/?gist=7b0b5ddc9fa74443e2257f80108d63df&version=stable
play.rust-lang.org/?gist=6cdb06cdd8dfa521045f5054d1cf2223&version=stable
rustbyexample.com/primitives/array.html
play.rust-lang.org/?gist=1c21581122ca98fc2b342dd0a989ca98&version=nightly&mode=release
play.rust-lang.org/?gist=a20ae380e856126347b419f65743373f&version=nightly&mode=release
gnu.org/licenses/>.
en.wikipedia.org/wiki/Advent_calendar
adventofcode.com/2017/about
doc.rust-lang.org/std/collections/struct.LinkedList.html
play.rust-lang.org/?gist=7487acd162ae615a85dca98654c2d889&version=stable
play.rust-lang.org/?gist=cba1239b4aa56b484c607c61e7a6b637
play.rust-lang.org/?gist=20bb760159cbd1ff5d5479c96f52c6e1
ocaml.org/learn/tutorials/garbage_collection.html
docs.python.org/3/library/exceptions.html#StopIteration
blog.rust-lang.org/2017/11/22/Rust-1.22.html
play.rust-lang.org/?gist=4f59385d7ea3cae44be11499cd1c25d2
play.rust-lang.org/?gist=0720b3a232a28b8e524ae589300745f7

Dylan Lopez
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
Michael Ward

Day 1 in C: codepad.org/CiFpQwfb

#include <stdio.h>

char INPUT[] = "1122";

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

Asher James
Asher James

1 in Python codepad.org/gyUmadgj
[code]#!/usr/bin/env python3

INPUT = "1122"

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

Jason Butler
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
Landon Hughes

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

Joshua Howard
Joshua Howard

codepad.org/LPJ86RtI
#include <stdio.h>

char INPUT[] = "123425";

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

codepad.org/cBpouX3o
#!/usr/bin/python3

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

Gabriel King
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
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
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
Andrew Nguyen

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

Juan Bell
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
Jackson Collins

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

James Wood
James Wood

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

Cameron Gomez
Cameron Gomez

Shut up and code.

Ayden Young
Ayden Young

My thoughts exactly...

Ethan Lee
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
Matthew Brooks

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

Carter Price
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
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
Michael Morales

spd-say -t child_female -p +100 faggot

Benjamin Murphy
Benjamin Murphy

Mathematica

Hunter Gomez
Hunter Gomez

Lighten up mate, these are only for fun.

Jaxon Allen
Jaxon Allen

maintainable code
for a Christmas challenge
who cares, faggot

Ethan Young
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
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
Asher Young

Here's something to soothe your gay rage

Leo Lopez
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
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
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
Ryder White

this
coding for free

Angel Wright
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
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
Cooper Jackson

this is what /g/tards actually believe

Brayden Ramirez
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
Landon Morgan

ocaml or some shit
no pattern matching
pajeet

Leo Powell
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
Ryder Baker

not an argument

James Nelson
James Nelson

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

Xavier Evans
Xavier Evans

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

Luke Lewis
Luke Lewis

You have to pay a monthly fee for private repos.

Liam Ortiz
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
Luke Barnes

Yeah but otherwise it's free.

James Barnes
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
Elijah Sullivan

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

Parker Jackson
Parker Jackson

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

Aiden Johnson
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 = 112

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

Angel Robinson
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
Elijah Edwards

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

Jackson Russell
Jackson Russell

watching tv

Julian Taylor
Julian Taylor

<not watching television

Owen Cooper
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
Lincoln Thompson

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

Robert Parker
Robert Parker

Day 2 is up.

Xavier Turner
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
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
Aiden Morales

there are A LOT of chinks on the leaderboard

Joseph Wright
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
Ayden Murphy

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

Joseph Martinez
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
Jaxson Howard

bully me
POST IT!

Angel Moore
Angel Moore

I ugh, don't have an account.

Dominic Turner
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
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
Oliver Torres

totally defeats the point of rushing then imo

Bentley Young
Bentley Young

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

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

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

Carson Taylor
Carson Taylor

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

Jose Hall
Jose Hall

I take that back, my part1 is marginally faster.

I haven't seen anyone using Ada yet.

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

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

Blake Lopez
Blake Lopez

Multithreaded solution: play.rust-lang.org/?gist=a66c52c2c097b90b9aa02b2e5b2e8b20&version=stable
extern crate num_cpus;
extern crate threadpool;
use threadpool::ThreadPool;
use std::sync::mpsc::channel;

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

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

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

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

Luis Sanchez
Luis Sanchez

I don't think the input size necessitates threading user

Nicholas Wright
Nicholas Wright

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

Wyatt Morales
Wyatt Morales

Could someone please screenshot part 2?

Evan Watson
Evan Watson

day 2let 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
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
Henry Richardson

no code
spotted the butthurt LARPer

Mason Fisher
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
Asher Morris

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

Christopher Jackson
Christopher Jackson

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

Josiah Bennett
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
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
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
Parker Miller

There is no hard requirement on performance you LARPfag.

Charles Lewis
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
John Rivera

Are you just pretending to be retarded?

Noah Howard
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
Jason Barnes

he just doesn't want to compare rust against ocaml for no reason
meanwhile:$ time python -c 'print 1'
1

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

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

Ryan Ortiz
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
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
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
Chase Torres

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

Isaac Flores
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
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
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
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
Zachary Powell

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

Josiah Turner
Josiah Turner

fucking hell this autism

Henry Cox
Henry Cox

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

Ayden Rivera
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
Alexander Hall

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

Camden Kelly
Camden Kelly

Horrifying indeed. What language is this?

Bentley Ross
Bentley Ross

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

Isaiah Allen
Isaiah Allen

yes, it's perl6.

Joshua Jackson
Joshua Jackson

Does it still have worse performance than perl5?

Adam Ortiz
Adam Ortiz

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

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

Jordan Murphy
Jordan Murphy

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

Levi Murphy
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
Eli Walker

Learn J or K.

Dominic Wood
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
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
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
Carter Morgan

Now do it in a real language (like C)

Nicholas Morgan
Nicholas Morgan

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

Hudson Stewart
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
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
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
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 ()) m

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

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

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

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

let spy_found = ref false

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

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

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

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

Colton Collins
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
Hudson Mitchell

semicolons
????????

Parker Roberts
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
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
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
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
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
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
Levi Baker

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

Luis Brown
Luis Brown

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

Jaxon Jones
Jaxon Jones

45

Camden Wood
Camden Wood

just change the input here:

Justin Flores
Justin Flores

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

Adam Powell
Adam Powell

well they are wrong

Dylan Ramirez
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
Logan Perry

codepad.org/ONnL9NnO
codepad.org/UzRjUfXs

Isaac Sullivan
Isaac Sullivan

is there an Holla Forums private leaderboard yet?

Joshua Jenkins
Joshua Jenkins

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

Sebastian Clark
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
Isaiah Flores

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

Bentley Clark
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
Carson King

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

Jaxon Garcia
Jaxon Garcia

what..?

Mason Smith
Mason Smith

nodev LARPer spotted
antisage btw

Jonathan Long
Jonathan Long

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

Luis Jenkins
Luis Jenkins

45 #MeToo

Nathan Sullivan
Nathan Sullivan

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

Brandon Barnes
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
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
Bentley Howard

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

Michael Clark
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
Jaxson Gray

it could be useful in code golf though

Landon Brooks
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
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
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
Christopher Ortiz

forgot that it's mathematica
Stallman does not approve it

Jeremiah Perry
Jeremiah Perry

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

Carson Ramirez
Carson Ramirez

Here is your goldstar, you earned it champ

Jonathan Thompson
Jonathan Thompson

c++ was a mistake

Samuel Rogers
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
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
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;
a

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

let valid_passphrases () =
List.fold_left (fun count phrase -> if valid_passphrase phrase then count + 1 else count)
0
(String.split_on_char '\n' passphrases)
part 1 is just this without the List.map (storing strings instead of sorted arrays of char). 'passphrases' is just a copy&paste of the phrases from the website, in a string
feels like the language is missing a Bytes.sort , though it's a pretty rare thing to want, and more obviously a string_to_array which I had to do manually here.

Jason Taylor
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
Alexander Robinson

too much typing


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

Ethan Johnson
Ethan Johnson

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

Juan Torres
Juan Torres

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

Charles Ramirez
Charles Ramirez

excuses

Michael Ortiz
Michael Ortiz

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

Anthony Wood
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
Levi Rogers

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

Caleb Parker
Caleb Parker

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

Dominic Evans
Dominic Evans

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

Charles Jackson
Charles Jackson

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

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

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

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

let no_anagrams = Fn.compose all_unique_words sort_words

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

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

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

Hudson Richardson
Hudson Richardson

Mathematica makes short work of it.

Elijah Lewis
Elijah Lewis

It can even be golfed shorter, this guy on reddit did it even nicer, hiding my explicit 'True'.
reddit.com/r/adventofcode/comments/7hf5xb/2017_day_4_solutions/dqqjj88/

Leo Miller
Leo Miller

oh yeah, it's the point-less style

Asher Cook
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
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
Nolan Reed

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

Isaac Gray
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
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
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
Jonathan Ramirez

the virgin haskeller
thinks functional languages are important
reads academic programming papers in his spare time just to understand how to write hello world
purchased a graph theory textbook
knows what a monad is
solves programming puzzles for fun
gives all his variables a type even though the compiler does it automatically
programs "for the sake of the craft"

THE CHADSNAKE
writes everything in python because it's the easiest
thinks "programming paradigms" are for loser nerds
has never spawned a thread in his life
takes all his algorithms unashamedly from stack overflow
first program was an automated trading script, written in half a day, exponential gains everyday
will never write a line of code for free or for fun
goes to sleep without thinking about computers

Nolan Reed
Nolan Reed

That's hilarious.

Nicholas Bennett
Nicholas Bennett

Thanks for the code review.

Christian Johnson
Christian Johnson

nub
O(n^2)

Gavin Rogers
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
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
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
Luke Jenkins

hash with no collision strategy
It uses linear probing though

Carter Perez
Carter Perez

oh. yeah I see it now.

Justin Hernandez
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 <- 0
end

let hash_asis = Hashtbl.hash

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

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

why is it not faster orz
(changed on hash functions because I don't understand them)
(no hash collision because I didn't want to rewrite code to store sorted value after I realized the mistake)

Kayden Parker
Kayden Parker

that syntax highlighting
no serious language uses ' for strings

Nathaniel Allen
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
Ayden Garcia

those comments
allaha huakbar

Jose Jackson
Jose Jackson

ocaml
benchmarksgame.alioth.debian.org/u64q/compare.php?lang=ocaml&lang2=rust

Daniel Jones
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
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
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
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
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
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
Nicholas Lewis

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

Cooper Adams
Cooper Adams

What are you trying to do here?

Sebastian Davis
Sebastian Davis

in the problem the last number per layer will always be an odd number squared
17 16 15 14 13
18 5 4 3 12
19 6 1 2 11
20 7 8 9 10
21 22 23 24 25

the while loop finds the first odd number that when squared is more then the input number.
that number is the length of one side.

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

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

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

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

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

Aaron Howard
Aaron Howard

i guess i should say shell not layer

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

Jace Hill
Jace Hill

Very noice.

Grayson Murphy
Grayson Murphy

check em'

Asher Wood
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
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
Xavier Diaz

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

Gabriel Ortiz
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
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 0

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

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

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

Charles Cruz
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
Wyatt Wright

I've already done it here:

Joshua White
Joshua White

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

Nathaniel Gonzalez
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
Luke Baker

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

Cooper Ross
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
Jayden Hernandez

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

Matthew Anderson
Matthew Anderson

Pretty substantial drop off from day 2 to 3.

Ryan Rogers
Ryan Rogers

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

Christopher Cooper
Christopher Cooper

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

Adam Sanchez
Adam Sanchez

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

Takes about 3 seconds.

Christian Thomas
Christian Thomas

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

Noah Fisher
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
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
Justin Bell

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

Brayden Cooper
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__
0
3
0
1
-3


use strict;
use warnings "all";

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

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

__DATA__
0
3
0
1
-3

Camden Lewis
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 < input
23948711

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

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

~ $ time ./dik < input
23948711

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

Perl6 truly is the future of computing.

Anthony Green
Anthony Green


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


~ $ time perl dik.pl < input
23948711

real 3.35s
user 3.34s
sys 0.00s

Nolan Williams
Nolan Williams

rip perl6, we hardly knew ya

Joseph Martinez
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
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
Christopher Baker

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

Robert Allen
Robert Allen

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

Cameron Peterson
Cameron Peterson

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

Adam Smith
Adam Smith

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

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

David Lee
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?

Cameron Adams
Cameron Adams

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

What language is this?

Ayden Allen
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
Mason Mitchell

are you retarded

Colton Collins
Colton Collins

wtf does part 2 of day 6 even mean?

Brandon Wright
Brandon Wright

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

Dominic Walker
Dominic Walker

close, but not exactly

Wyatt Brooks
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
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) blocks

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

let smooth a =
let seen = Hashtbl.create (Array.length a) in
let wtf a = String.concat ":" (Array.fold_left (fun acc n -> string_of_int n :: acc) [] a) in
let steps = ref 0 in
while None = (Hashtbl.find_opt seen (wtf a)) do
Hashtbl.add seen (wtf a) !steps;
smooth_from a (max_block a);
steps := !steps + 1
done;
(!steps, !steps - Hashtbl.find seen (wtf a), a)
1. the 'wtf' function is of course a wtf; I should have a real hash function for the array and use that instead.
2. the max block should probably be tracked while reallocating, so that it doesn't have to be looked up again
3. with the input as small as they are one option would be to use Bytes (a mutable string) instead of an array of ints. that gets rid of the wtf function

Anthony Rivera
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
James Russell

Day 6 (cleaned up a bit)

Parker Fisher
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
Aiden Torres

nevermind, I misunderstood the question

Easton Bailey
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
Jack Bailey

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

Matthew Lopez
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
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
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;
!maxi

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

Angel Perez
Angel Perez

rare instance found of actually readable Haskell
naturally the author posted it with a sincere apology. that community is fuckedimport Data.Sequence (Seq)
import qualified Data.Sequence as Seq

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

import Data.List

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

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

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

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

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

Henry Martinez
Henry Martinez

(((functional programming)))

Ayden Jenkins
Ayden Jenkins

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

Eli Cruz
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
Nicholas Sanchez

You don't need to????

Jason Butler
Jason Butler

I want to!

Hudson Sanchez
Hudson Sanchez

Take your autism and leave

John Clark
John Clark

/reddit/index.html

Gabriel James
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
Blake Cook

binary tree
too slow
SIMD
llvm already does that for me

Ethan Baker
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
David Cox

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

Cooper Long
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
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
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
James Howard

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

Wyatt Bell
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;
};

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

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

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

return val;
}

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

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

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

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

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

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

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

return -1;
}

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

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

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

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

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

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

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

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

return 0;
}

[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/null
Total steps: 4074

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

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

Jackson Taylor
Jackson Taylor

WEEEEEEEEEEEEEEEEEEEEEEEEW LAD
why is this so fucking verbose? not even my optimized rust version that implements its own hashmap is this fucking long.
is your blazechan code also this shit?

Anthony James
Anthony James

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

Kayden Adams
Kayden Adams

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.

Adrian Bell
Adrian Bell

128 bytes
Brain melt, i meant 16 ints.

Jackson Adams
Jackson Adams

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

Nathan Adams
Nathan Adams

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

polite bump

Dominic Bailey
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.
en.wikipedia.org/wiki/Advent_calendar

Colton Gomez
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.
en.wikipedia.org/wiki/Advent_calendar
And?

Andrew Stewart
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
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.
adventofcode.com/2017/about
Advent of Code is a series of small programming puzzles for a variety of skill levels. They are self-contained and are just as appropriate for an expert who wants to stay sharp as they are for a beginner who is just learning to code. Each puzzle calls upon different skills and has two parts that build on a theme.

Samuel Thompson
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
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
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
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
Samuel Gutierrez

binary tree
You could try a bloom filter.

Brayden Nelson
Brayden Nelson

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


import re
from collections import defaultdict

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


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


all = set()
not_bottom = set()


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


all_linked = defaultdict(P)

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

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


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


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


print(check_weight(root))

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

Ryder Martinez
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
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
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
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
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
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 sys
import re
import collections

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

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

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

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

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

return list(trees.values())

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

return climb(trees[0])

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

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

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

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

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

print(parent, commons, diff)

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

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

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

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

[email protected]:~$ time python3 day7.py <day7input >/dev/null

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

C version coming after the Py3 implementation.

Carter Martinez
Carter Martinez

Pajeets having trouble traversing a tree

Ryan Ramirez
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
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;
}

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

ungetc(c, stdin);
return val;
}

static int line;

Node *
node_from_line() {
line++;

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

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


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

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

getchar(); // space

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

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

return NULL;
}

1/3

Jackson Russell
Jackson Russell

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

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

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

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

struct uniq {
int weight, count;
};

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

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

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

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

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

Node *parent = root;

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

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

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

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

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

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

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

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

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

return 0;
}

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

2/2
7ms
F
Valgrind shows no leaks. This time I used a hashmap.

Matthew Stewart
Matthew Stewart

Don't you know what a pastebin is?

Aaron Long
Aaron Long

GPL header
Made me smile

Jace Mitchell
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
Lincoln Rodriguez

Do you want me to modify and study your comment?

Isaac Cooper
Isaac Cooper

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

Kevin Butler
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
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
doc.rust-lang.org/std/collections/struct.LinkedList.html
How is this relevant to this challenge?
LOL @ language can't have trees with parents
Why would you ever do that? Also, how is this relevant to the challenge?
LOL @ safety from using it for anything but toy projects
https://en.wikipedia.org/wiki/Rust_(programming_language)#Projects_using_Rust

Juan Bennett
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
Michael Watson

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

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

Noah Adams
Noah Adams

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

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

Hudson Howard
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
Daniel James

coders
guys in the background clearly not doing coding
well done

Dylan Watson
Dylan Watson

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

Kayden Lopez
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
Elijah Ross

this is worse than c++

Matthew Long
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
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
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
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
Luke Jenkins

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

Dylan Clark
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
John Collins

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

Zachary Clark
Zachary Clark

Cheating with eval


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

Dylan Bell
Dylan Bell

Day 8 Golfed
203 characters


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

Michael Anderson
Michael Anderson

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

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

Jordan Campbell
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
Kayden Bennett

197 characters
no need to compare strings by equality here :D

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

Brayden Morris
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 sys

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

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

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

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

mv = max(mv, regs[reg])

return (regs, mv)

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

Did a shitty version of this in a repl in ~15 minutes and got 364th and 447th worldwide respectively. C version should come fairly soon.
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
Hunter Parker

tl;dr

Elijah Collins
Elijah Collins

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

Henry Anderson
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
Blake Harris

Still longer than Python with 197 characters.

Alexander Sanders
Alexander Sanders

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

Benjamin Collins
Benjamin Collins

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

David Nelson
David Nelson

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

Joshua Roberts
Joshua Roberts

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

Elijah King
Elijah King

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

Parker Nelson
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
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
Benjamin Powell

Code golf is a legitimate thing btw.

Robert Walker
Robert Walker

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

Wyatt Hernandez
Wyatt Hernandez

And so is optimization tbh fam.

Hudson Allen
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
Carter Turner

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

Jonathan Hughes
Jonathan Hughes

I said day 7

Adrian Sanders
Adrian Sanders

Oh right. No. Maybe Steve will.

Jackson Powell
Jackson Powell

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

Nathan Kelly
Nathan Kelly

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

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

Adam Gonzalez
Adam Gonzalez

[email protected] ~ % grep unwrap day8.rs | wc -l
13

Justin Carter
Justin Carter

muh LOC
LOL. >>834113
stfu you stupid turkoachh

Cameron Hernandez
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
Parker Gray

grep unwrap >>834487 | wc -l
6

So? Would you rather prefer undefined behavior?

Anthony Ramirez
Anthony Ramirez

stfu you stupid turkoachh
oachh
Please, it's turkroach.
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
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
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
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
Jace Diaz

good thread
shilling for some reddit "puzzle" crap
lmfao

Andrew Turner
Andrew Turner

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

Leo Kelly
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
Angel Carter

refcounting is bad
pic related
Give one argument against it.

Jonathan Morgan
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
Evan Gomez

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

Brody Ward
Brody Ward

Rc<RefCell<…
lol

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

Cameron Adams
Cameron Adams

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

Evan Johnson
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
Lincoln James

day 8 was fun. ocaml:type modop = Inc | Dec
type condop = Gt | Ge | Eq | Ne | Lt | Le
type cond = If of (string * condop * int)

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

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

Jackson Thomas
Jackson Thomas

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

Ethan Taylor
Ethan Taylor

unwrap
beautiful

Bentley Moore
Bentley Moore

hurr durr
XDDDDDD
not an argument

Alexander Russell
Alexander Russell

No need to be so rusty friendo

Kevin Sanders
Kevin Sanders

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

Connor Ward
Connor Ward

rust is being discussed
link python

Hunter Sullivan
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
Jeremiah Collins

Would Rustfagsdevs consider adding ? functions for returning an Option and exploding by default?
Added in v1.22
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
Luis Torres

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

Michael Jackson
Michael Jackson

also File::open returns a Result not an Option

Levi Harris
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
Asher Bell

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

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

Andrew Adams
Andrew Adams

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

fuck off kampfy

Leo Myers
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
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
Benjamin Hall

i am now imkampfy
ok

Carter Scott
Carter Scott

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

Lincoln Powell
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
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
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
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
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
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
Parker Garcia

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


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

Ryder Kelly
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
Ayden King

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

Liam Lopez
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
Evan Nguyen

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

Joshua Hughes
Joshua Hughes

Good job.

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

Sebastian Williams
Sebastian Williams

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

Julian Turner
Julian Turner

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

Liam Martinez
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
Henry Sanchez

Nice work.

James Wright
James Wright

source?

Luke Gomez
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:$ ./day9
mine 10000 iterations: 0.000058 s
rust 10000 iterations: 0.000057 s

$ ./day9
mine 10000 iterations: 0.000058 s
rust 10000 iterations: 0.000056 s

$ ./day9
mine 10000 iterations: 0.000063 s
rust 10000 iterations: 0.000056 s

$ ./day9.byte
mine 10000 iterations: 0.000251 s
rust 10000 iterations: 0.000491 s
the timing is the real timing / iterations ofc.

Isaiah Cox
Isaiah Cox

How many of you guys actually log into the site?

Lucas Johnson
Lucas Johnson

you have to log into it to get the puzzles. IIRC I just used a github throwaway.

Matthew Stewart
Matthew Stewart

New thread: New thread: New thread: New thread: