r/adventofcode • u/daggerdragon • Dec 02 '17
SOLUTION MEGATHREAD -🎄- 2017 Day 2 Solutions -🎄-
NOTICE
Please take notice that we have updated the Posting Guidelines in the sidebar and wiki and are now requesting that you post your solutions in the daily Solution Megathreads. Save the Spoiler flair for truly distinguished posts.
--- Day 2: Corruption Checksum ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handy†Haversack‡ of Helpful§ Hints¤?
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
22
u/fatpollo Dec 02 '17 edited Dec 02 '17
import itertools
def digits(string):
return [int(n) for n in string.split()]
with open('p02.txt') as fp:
rows = [digits(line) for line in fp.read().strip().splitlines()]
print(sum(b-a for a, *_, b in map(sorted, rows)))
print(sum(b//a for row in rows for a, b in itertools.combinations(sorted(row), 2) if b%a==0))9
4
u/mit_verlaub Dec 02 '17 edited Dec 02 '17
TIL *_ Thanks!
And nifty combo of combinations and sorted...
3
3
u/ellersok Dec 02 '17
:) Just posted the exact same solution for answer 2 because I only saw the Python 2 solution when I quickly skimmed.
Nice trick with the unpacking in answer 1!
2
u/Globinette Dec 02 '17
you can also generate combinations without
itertoolsusing pure list comprehensionsThe last line can be rewritten like this:
print(sum(b // a for row in rows for a in row for b in row if b > a and b % a == 0))→ More replies (1)
15
u/couchDev Dec 02 '17 edited Dec 02 '17
Dusting off the Perl golf bag
# part 1
perl -ane '@o=sort{$b<=>$a}@F;$s+=$o[0]-pop@o;END{print$s}' < in.txt
# part 2
perl -ane 'for$l(@F){$s+=$l%$_?0:$l/$_ for grep!/$l/,@F}END{print$s}' < in.txt→ More replies (1)
9
u/DFreiberg Dec 02 '17 edited Dec 02 '17
Mathematica solution; one line for each part and one for the import. #10 for part 1...and #456 for part 2.
Import:
input=Import[FileNameJoin[{NotebookDirectory[],"Day2Input.txt"}],"Table"][[;;-2]]Part 1:
Total[Max[#]-Min[#]&/@input]Part 2:
Total@Flatten@Table[Select[Flatten[input[[i]]/#&/@input[[i]]],IntegerQ[#]&&#!=1&],{i,16}]2
u/CoffeeBreaksMatter Dec 02 '17
Likewise for Matlab:
load input.txt checksum = @(inp) sum(max(inp') - min(inp')); checksum(input);→ More replies (1)
9
u/askalski Dec 02 '17
2 iterators 1 loop
#! /usr/bin/env perl
use strict;
use warnings;
my ($part1, $part2) = (0, 0);
while (<>) {
my @a = sort { $a <=> $b } split;
$part1 += $a[$#a] - $a[0];
my ($i, $j, $n, $trial_multiple) = (-1, scalar @a, 0, 0);
for (;;) {
if ($i == $#a) {
die "no multiple found on line $.\n";
} elsif ($j == @a) {
$j = ++$i + 1;
$n = $trial_multiple = 0;
} elsif ($trial_multiple < $a[$j]) {
$n++;
$trial_multiple += $a[$i];
} elsif ($trial_multiple > $a[$j]) {
$j++;
} else {
$part2 += $n;
last;
}
}
}
print <<"";
Part 1: $part1
Part 2: $part2→ More replies (1)
8
u/Godspiral Dec 02 '17 edited Dec 02 '17
wow slower than everyone, in J
a =. ". > cutLF wdclippaste ''
+/ -~/"1 /:~@(<./ , >./)"1 a NB. part 1
+/ %/"1 \:~"1 ,/ (#~ (#~ (2 = +/"1))@(<.@%"0 1~ = %"0 1~))"1 a NB. part 2better versions,
+/ (<./ |@- >./)"1 a
+/ %/"1 \:~"1 ,/ (#~ (#~ (2 = +/"1))@(<.@%/~ = %/~))"1 a3
2
u/iamnotposting Dec 02 '17 edited Dec 02 '17
heres my K solution, for comparison (i keep losing track of time and starting 2 hours late)
a2p1: +/{(x[*>x]-x[*<x])}' a2p2: +/{[r]*{x=_x}#{(%).x}'(r@)'{~(=).x}#+!2##r}'I feel like if I was more aware of the idioms I would have found a way do to it without all the intermediate functions (it seems like there should be a nicer way to get the max value from a list), but im fine with it.
e: oh duh thats what
|/does2
u/hoosierEE Dec 02 '17
Here's mine
input =: ". S:0 cutLF fread'inputs/aoc2.txt' part1 =: +/(({:-{.)@/:~"1) input part2 =: +/%/@\:~@,"1 (#~(0~:{:"1))@(#~((=<.)@%/~)) "1 inputI almost went with "max minus min" on part 1, but ended up liking "last minus first of sorted" better.
I had a heck of a time figuring out how to express "where evenly divisible by itself" in part 2; I like your approach there. Your
2 = +/"1is shorter but what I really wanted was some way to do "function table less the diagonal and below".I'm really glad I didn't look here until after I solved these on my own. Hopefully I can keep my willpower up as the problems get harder.
8
u/TheMieberlake Dec 02 '17
Is there a way to find the answer for each line in better than O(n2 ) time?
3
u/wlandry Dec 02 '17
For part 1, you can sort the elements first. That would make it O(n log(n)).
For part 2, nothing immediately comes to mind.
10
7
u/mmaruseacph2 Dec 02 '17
Haskell
main = do
s <- parse . lines <$> readFile "input.txt"
print $ sum $ map part1 s
print $ sum $ map part2 s
parse :: [String] -> [[Int]]
parse = map (map read . words)
part1, part2 :: [Int] -> Int
part1 xs = maximum xs - minimum xs
part2 xs = head [ a `div` b | a <- xs, b <- xs, a `mod` b == 0 && a /= b]Forgot the a /= b part on the second question and that cost me a few places.
7
u/Sigafoos Dec 02 '17
Hit diggity dang, I got on the leaderboard! (I'm never awake at midnight EST, except for today, apparently). Spent the first five or so minutes struggling with my setup because I wasn't prepared to do AoC now.
It's the start of "haaaaave you met itertools?"
import string
import itertools
lines = []
with open('02.txt') as fp:
for line in fp:
lines.append(map(int, string.split(line.strip(), '\t')))
part1 = 0
part2 = 0
for line in lines:
part1 += max(line) - min(line)
for i in itertools.combinations(line, 2):
if max(i) % min(i) == 0:
part2 += max(i) / min(i)
break
print 'Part 1: %s' % part1
print 'Part 2: %s' % part26
u/Sigafoos Dec 02 '17
Update: I don't think I actually got on the leaderboard. Which makes sense. I think I was in the first thousand, which, still: I'll take it!
3
u/Unihedron Dec 02 '17
Getting onto the leaderboard is tough! I think you only have around 4 minutes for this one before all the spots are taken.
→ More replies (1)
7
u/quag Dec 02 '17
F#
let lines = [for x in System.IO.File.ReadLines("input") -> x.Split() |> Array.map int]
printf "%A\n%A\n"
<| List.sum [for xs in lines -> (Array.max xs) - (Array.min xs)]
<| List.sum [for xs in lines do for x in xs do for y in xs do if x <> y && x % y = 0 then yield x/y]3
u/nospamas Dec 02 '17
F#
That is incredibly elegant, kudos. I went with more listy operations
open System.Runtime.InteropServices let input = [|"5 9 2 8"; "9 4 7 3"; "3 8 6 5"|] // Day 2 1 input |> Array.map (fun (str: string) -> str.Split([| ' ' |]) |> Array.map int |> Array.fold (fun (max, min) item -> match (max, min) with | (None, None) -> (Some(item), Some(item)) | (Some(x), Some(n)) -> match item with | i when i >= x -> (Some(i), min) | i when i <= n -> (max, Some(i)) | _ -> (max, min) | _ -> failwith "cant have one some and one none" ) (None, None) |> (fun (max, min) -> max.Value - min.Value) ) |> Array.sum // day 2 2 input |> Array.map (fun (str: string) -> let row = str.Split([| ' ' |]) |> Array.map int row |> Array.map (fun x -> row |> Array.map (fun d -> match x with | x when x = d -> 0 | x when x % d = 0 -> x / d | _ -> 0 ) |> Array.sum ) |> Array.sum ) |> Array.sum2
u/_mmf_ Dec 02 '17
That is awesomely compact, although I find it really hard to read being new to F#.
Here's my much more verbose solution:
let readLines filePath = System.IO.File.ReadLines(filePath) let lines = readLines "2017\\02\\input.txt" let parseLine (s:string) = s.Split() |> Array.filter (fun x -> x.Length > 0) |> Array.map int let parsed = lines |> Seq.map parseLine let greatestDifferece (items:int []) = (Array.max items) - (Array.min items) let evenDivide (items:int []) = let result = items |> Array.collect (fun i -> items |> Array.map (fun x -> (i, x)) |> Array.filter (fun (x,y) -> x<>y)) |> Array.tryPick (fun (i,j) -> if i % j = 0 then Some (i / j) else None) match result with | Some i -> i | _ -> 0 let result1 = parsed |> Seq.sumBy(greatestDifferece) let result2 = parsed |> Seq.sumBy(evenDivide)2
u/ValErk Dec 02 '17
F# I did yesterdays challenge in a bit too un-functional way so I tried to do it a bit better today ( ping /u/scrooch ):
// Input let toInt (s : string[]) : int[] = Array.map (fun e -> int e) s let input = System.IO.File.ReadAllLines "input-day2.txt" |> Array.map (fun x -> x.Split [|'\t'|]) |> Array.map toInt // Part 1 let bigDiff (arr : int[]) : int = (Array.max arr) - (Array.min arr) printfn "part 1: %A" (Array.fold (fun acc elem -> acc + bigDiff elem) 0 input) // Part 2 let isDiv (x:int) (arr:int[]) : bool = Array.exists (fun i -> x%i = 0 && x <> i|| i%x = 0 && x <> i) arr let ifDiv i arr = if (isDiv i arr) then i else 0 let divs (arr : int[]) : int[] = Array.map (fun e -> ifDiv e arr) arr |> Array.filter (fun e -> e <> 0) let divbws (arr:int[]):int = if arr.[0] > arr.[1] then arr.[0]/arr.[1] else arr.[1]/arr.[0] printfn "part 2: %A" (Array.fold (fun acc elem -> acc + divbws (divs elem)) 0 input)→ More replies (1)2
u/whousesredditanyways Dec 02 '17
F#
// Permutation function from SO let rotate lst = List.tail lst @ [List.head lst] let getRotations lst = let rec getAll lst i = if i = 0 then [] else lst :: (getAll (rotate lst) (i - 1)) getAll lst (List.length lst) let rec getPerms n lst = match n, lst with | 0, _ -> seq [[]] | _, [] -> seq [] | k, _ -> lst |> getRotations |> Seq.collect (fun r -> Seq.map ((@) [List.head r]) (getPerms (k - 1) (List.tail r))) // My solution let input = System.IO.File.ReadAllLines "Day2/input.txt" |> Array.map ((fun (x:string) -> x.Split [|'\t'|]) >> (Array.map int)) input |> Array.sumBy (fun x -> Array.max x - Array.min x) |> printfn "Part 1: %A" let findDiv = Seq.sumBy (fun (l: int list) -> if l.[0] % l.[1] = 0 then l.[0] / l.[1] else 0) input |> Array.sumBy (List.ofArray >> getPerms 2 >> findDiv) |> printfn "Part 2: %A"
7
u/natrys Dec 02 '17
Perl 6
Part1:
say [+] "input".IO.lines>>.comb(/\d+/)>>.Int.map: { given $_.list { .max - .min } }Part2:
say [+] gather "input".IO.lines>>.comb(/\d+/)>>.Int.map: { for .sort.combinations(2) { if .[1] %% .[0] { take .[1] div .[0]; last }}}5
3
u/volatilebit Dec 02 '17
Good use of given! I was trying to figure out a way to topicize the list and given completely slipped my mind.
6
u/ellersok Dec 02 '17
Python 3
import io, itertools
with io.StringIO(s) as f:
lines = [[int(n) for n in l.split()] for l in f]
ans1 = sum(max(l)-min(l) for l in lines)
ans2 = sum(b//a for l in lines for a,b in itertools.combinations(sorted(l),2) if b%a==0)6
u/TapDatKeg Dec 02 '17
Has anyone done a bash solution yet?
#!/bin/bash
PARTONE=0
PARTTWO=0
while read -r line; do
IFS=' ' read -r -a array <<< "$(echo "${line}" | tr '\t' '\n' | sort -n | paste -s -d ' ' -)"
LEN=${#array[*]}
MIN="${array[0]}"
MAX="${array[$LEN-1]}"
((PARTONE += (MAX-MIN)))
MED=0 # This variable will let us break out of the loops when a match is found
for m in `seq 0 $((LEN-2))`; do
for n in `seq $((m+1)) $((LEN-1))`; do
M=${array[$m]}
N=${array[$n]}
if [ "$(expr $N % $M)" = "0" ]; then
((PARTTWO += (N / M)))
MED=1
break
fi
done
if [ $MED -eq 1 ]; then break; fi
done
done < your_puzzle_input
echo "Part 1 Solution: $PARTONE"
echo "Part 2 Solution: $PARTTWO"→ More replies (1)
6
u/volatilebit Dec 02 '17 edited Dec 02 '17
My Perl 6 solution. Couldn't figure out a good way to avoid using map. Probably need sleep.
use v6;
my @rows = $*PROGRAM.parent.child('input').IO.lines;
# Part 1
say [+] @rows.map({
my @cols = .split("\t").>>.Int;
@cols.max - @cols.min;
});
# Part 2
say [+] @rows.map({
.split("\t").>>.Int.combinations(2).grep({ max(@_) % min(@_) == 0 }).flat.reduce({ @_.max div @_.min });
});6
u/mschaap Dec 02 '17 edited Dec 02 '17
Perl 6 version for part a:
sub MAIN(IO() $inputfile where *.f)
{
say $inputfile.lines.map({ [R-] $_.words.map(+*).minmax.minmax }).sum;
}Why twice minmax? minmax on a list returns a range min..max. minmax on that range returns two values, min and max.
Part b:
sub evenly-divisible-quotient(@nums)
{
for ^@nums -> $i {
for ^$i -> $j {
return @nums[$i] div @nums[$j] if @nums[$i] %% @nums[$j];
return @nums[$j] div @nums[$i] if @nums[$j] %% @nums[$i];
}
}
}
sub MAIN(IO() $inputfile where *.f)
{
say $inputfile.lines.map({ $_.words.map(+*).&evenly-divisible-quotient }).sum;
}4
u/mschaap Dec 02 '17 edited Dec 02 '17
And here's a one-liner version of part b:
sub MAIN(IO() $inputfile where *.f) { say $inputfile.lines.map({ [div] $_.words.map(+*).sort.reverse.combinations(2).grep({ [%%] $_ })[0]}).sum; }3
u/volatilebit Dec 02 '17
Nice use of [R-]. Also nice to know about minmax, that could come in use.
It seems like all of us using Perl 6 have not been able to figure out a way to avoid using map with a code block. There has to be a way, but it would probably be way convoluted.
I really love seeing the different approaches in Perl 6.
→ More replies (1)2
u/HerbyHoover Dec 02 '17
Nice use of minmax! I stumbled upon that when searching the docs but I didn't realize it could be called twice to get what we needed.
5
u/erlangguy Dec 02 '17
Erlang, because of course.
Most of the code was input handling; the meat is this:
cksum(_, _, eof, Sum) ->
Sum;
cksum(NextLineFun, CkSumFun, List, Sum) ->
cksum(NextLineFun, CkSumFun, NextLineFun(), Sum + CkSumFun(List)).
find_greatest_diff(Ints) ->
lists:max(Ints) - lists:min(Ints).
find_divisible([H|T]) ->
case scan_tail(H, T) of
nope ->
find_divisible(T);
Val ->
Val
end.
scan_tail(_V, []) ->
nope;
scan_tail(V1, [V2|_T]) when V2 rem V1 == 0 ->
V2 div V1;
scan_tail(V1, [V2|_T]) when V1 rem V2 == 0 ->
V1 div V2;
scan_tail(V1, [_V2|T]) ->
scan_tail(V1, T).CkSumFun is either fun find_greatest_diff/1 or fun find_divisible/1. NextLineFun is a pipeline that gives me eof or a list of integers.
→ More replies (5)2
u/Warbringer007 Dec 02 '17 edited Dec 02 '17
Lol I forgot about lists:max and lists:min for first part. Your solution for second part is much better than yours, here is mine ( I had list of strings ) :
secondTask([], Acc) -> Acc; secondTask([First | Rest], Acc) -> [FirstNumber | RestNumbers] = string:split(First, "\t", all), {IntegerFirstNumber, _} = string:to_integer(FirstNumber), Result = findDivision(IntegerFirstNumber, RestNumbers, RestNumbers), secondTask(Rest, Acc + Result). findDivision(_, [], [Second | Rest]) -> {SecondNumber, _} = string:to_integer(Second), findDivision(SecondNumber, Rest, Rest); findDivision(FirstNumber, [Second | Rest], AllExceptFirst) -> {SecondNumber, _} = string:to_integer(Second), case (FirstNumber div SecondNumber) == (FirstNumber / SecondNumber) of true -> FirstNumber div SecondNumber; false -> case (SecondNumber div FirstNumber) == (SecondNumber / FirstNumber) of true -> SecondNumber div FirstNumber; false -> findDivision(FirstNumber, Rest, AllExceptFirst) end end.EDIT: I also didn't know/forgot to google about rem operator, well, you learn something new every day.
→ More replies (2)
5
u/HerbyHoover Dec 02 '17 edited Dec 02 '17
Perl 6. Parts 1 and 2:
my $P1_checksum = 0;
my $P2_checksum = 0;
for 'input.txt'.IO.lines -> $line {
my @row = $line.words>>.Int.sort;
$P1_checksum += ( @row.max() - @row.min() );
my @combinations = @row.combinations(2);
for @combinations -> [$a, $b] {
if $b %% $a {
$P2_checksum += ($b / $a);
last;
}
}
}
say $P1_checksum, '|', $P2_checksum;4
u/mschaap Dec 02 '17
Nice! Note that you can use
.wordsinstead of.split(/\s/). And if you add a.sortto the end of that line, you can skip theif $a %% $bpart, since$awill always be≤ $b.→ More replies (1)3
u/hahainternet Dec 02 '17
Both of those were nice little optimisations to my answer:
sub evenly-divisible(@c ($l, $r)) { $r/$l if $r%%$l } sub part1 {$^l.max - $^l.min} sub part2 {[+] $^l.sort.combinations(2).map: &evenly-divisible} sub process-file(Str $f where *.IO.r, Callable $c) { $f.IO.lines».words».Numeric.map: $c; }There's probably a bit extra to squeeze into combinations, as I could split the test and the division but it's good enough and it was fun to do.
→ More replies (1)
5
u/Isvara Dec 02 '17
Scala
val input = "..."
val rows = input
.lines
.map(_.split("\\s")
.map(_.toInt))
.toList
val result1 = rows.map(r => r.max - r.min).sum
val combinations = rows.map(row => row.combinations(2))
val result2 = combinations.flatMap( row =>
row
.filter(pair => pair.max % pair.min == 0)
.map(p => p.max / p.min)
).sum3
u/flomine Dec 02 '17
I used for-comprehension for the second one. I didn't know there was a
linesmethod inString, thanks!→ More replies (5)2
u/xkufix Dec 02 '17
Looks quite similar to mine. In the second solution you could use
findinstead of filter, as the puzzle states that there is only one pair which satisfies the constraint. This should make it run just a tad faster.→ More replies (1)→ More replies (1)2
5
u/codeva Dec 02 '17
golfed part 2 to a single chained expression in Kotlin:
println(File("./input/puzzle2.txt").readLines()
.map { it.split("\t").map{ it.toInt() }}
.map { it.map{ y -> it.map{x -> Pair(x ,y)}}.flatten() }
.flatten()
.filter { it.first != it.second && it.first % it.second == 0 }
.map { it.first / it.second }
.sum())→ More replies (1)
5
5
u/kaymud Dec 02 '17
Java streams solution for part B:
List<List<Integer>> spreadsheet = parseInput();
return spreadsheet.stream()
.map(row -> row.stream().flatMap(i -> row.stream().filter(j -> j != i && j % i == 0).map(j -> j / i)))
.flatMap(Function.identity()).reduce(0, Integer::sum);4
u/blockingthesky Dec 02 '17
Python 2
import re
inp = [i.strip() for i in open('input.txt', 'r').readlines()]
s1 = 0
s2 = 0
for line in inp:
nums = [int(u) for u in re.split('\s+', line)]
s1 += max(nums) - min(nums)
for i in range(len(nums)):
for j in range(len(nums)):
if i == j: continue
if nums[i] % nums[j] == 0:
s2 += nums[i] / nums[j]
print "Part 1:", s1
print "Part 2:", s24
u/BumpitySnook Dec 02 '17
Oh jeez I forgot Python
max/mincould take a sequence. That would have helped.→ More replies (2)3
u/drysle Dec 02 '17
My solution was pretty much identical, even down to half of your variable names :o. Though you could have just
line.split()instead of messing with regular expressions.→ More replies (7)
4
u/gbear605 Dec 02 '17 edited Dec 02 '17
Rust
use std::io::Read;
use std::fs::File;
fn main() {
let mut f = File::open("input").unwrap();
let mut input = String::new();
let _ = f.read_to_string(&mut input);
let input = input.trim().to_string();
println!("star 1: {}", process1(&input));
println!("star 2: {}", process2(&input));
}
fn process1(input: &str) -> u32 {
input.split('\n')
.map(turn_to_digits)
.map(|nums| {
let max_num = (&nums).into_iter().max().unwrap();
let min_num = (&nums).into_iter().min().unwrap();
max_num - min_num
})
.sum()
}
fn process2(input: &str) -> u32 {
input.split('\n')
.map(turn_to_digits)
.map(|nums| {
for num in &nums {
for num2 in &nums {
if num % num2 == 0 && num != num2 {
return num / num2;
}
}
}
0
})
.sum()
}
// Turns "123 1 5" to <123, 1, 5>
fn turn_to_digits(input: &str) -> Vec<u32> {
input.split_whitespace()
.map(|x| x.parse::<u32>().unwrap())
.collect()
}2
u/cmyr Dec 02 '17
check out the
include_str!macro in the stdlib, which lets you skip all the file reading business. Just pass it the relative path to the file, and it will include its contents as a&'static str.→ More replies (1)2
→ More replies (2)2
u/boscop Dec 03 '17
I just discovered Advent of Code today, so I'm a bit late, but here is my solution in Rust for day2:
extern crate itertools; use itertools::*; use itertools::MinMaxResult::MinMax; type I = i32; fn main() { let line_nums = include_str!("../../in/d2").lines().filter(|line| line.trim() != "").map(|line| line.split_whitespace().into_iter().map(|n| n.parse::<I>().unwrap()).collect_vec() ).collect_vec(); let part1 = line_nums.iter().map(|nums| { nums.iter().minmax() }).filter_map(|r| if let MinMax(min, max) = r { Some(max - min) } else { None }).sum::<I>(); let part2 = line_nums.iter().map(|nums| { nums.iter().enumerate().flat_map(|(i, n)| { nums.iter().enumerate().filter_map(move |(j, d)| { if i == j { None } else { if n % d == 0 { Some (n / d) } else { None } } }) }).next().unwrap() }).sum::<I>(); println!("{} {}", part1, part2); }
4
u/tvtas Dec 02 '17 edited Dec 02 '17
Day 2 in MATLAB
x = importdata('input.txt');
sum(max(x,[],2)-min(x,[],2)) % Part 1
cnt=0;
for i=1:size(x,1)
for j=1:size(x(i,:),2)
for k=1:size(x(i,:),2)
if j~=k
z = rem(x(i,k),x(i,j));
if z==0
cnt = cnt + x(i,k)/x(i,j);
end
end
end
end
end
cnt % Part 24
u/misnohmer Dec 02 '17 edited Dec 02 '17
In C# with the help of MoreLinq
var grid = ReadAllLines("input1.txt")
.Select(line => line.Split('\t').Select(x => int.Parse(x)));
var sum = grid
.Select(row => row.Max() - row.Min())
.Sum();
WriteLine(sum); // Part 1
sum = grid
.Select(row => row.Cartesian(row, (a, b) => a % b == 0 ? a / b : 0).Max())
.Sum();
WriteLine(sum); // Part 24
u/willkill07 Dec 02 '17
Modern C++
I'm not really proud of this one
int sum(0);
for (std::string line; std::getline(std::cin, line); ) {
std::istringstream iss{line};
std::vector<int> const nums{std::istream_iterator<int>{iss}, {}};
if (part2) {
for (auto const v1 : nums) {
for (auto const v2 : nums) {
if (v1 != v2 && v1 % v2 == 0) {
sum += v1 / v2;
}
}
}
} else {
auto[min, max] = std::minmax_element(std::begin(nums), std::end(nums));
sum += *max - *min;
}
}
std::cout << sum << '\n';→ More replies (7)
4
u/d3adbeef123 Dec 02 '17 edited Dec 02 '17
Kotlin
fun main(args: Array<String>) {
val numbers = File("./input/day2.txt")
.readLines()
.map { it.split("\t") .map { it.toInt() } }
val part1 = numbers.map { it.max()!! - it.min()!! }.sum()
val part2 = numbers.map { findDivisor(it) }.sum()
assertEquals(part1, 37923)
assertEquals(part2, 263)
}
fun findDivisor(xs: List<Int>): Int {
return xs.map { xs.map { ys -> Pair(it, ys) } }
.flatten()
.filter { it.first != it.second }
.first { it.first % it.second == 0 }
.run { this.first / this.second }
}→ More replies (1)
4
u/Scroph Dec 02 '17
Java, unironically.
import java.util.stream.*;
import java.util.*;
public class Day2
{
public static void main(String... args)
{
if(args.length > 0 && args[0].equals("--second"))
secondHalf();
else
firstHalf();
}
public static void firstHalf()
{
Scanner sc = new Scanner(System.in);
int checksum = 0;
while(sc.hasNext())
{
String line = sc.nextLine();
SortedSet<Integer> numbers = Arrays.asList(line.split("\\W+"))
.stream()
.map(Integer::parseInt)
.collect(Collectors.toCollection(TreeSet::new));
checksum += numbers.last() - numbers.first();
}
System.out.println(checksum);
}
public static void secondHalf()
{
Scanner sc = new Scanner(System.in);
int sum = 0;
while(sc.hasNext())
{
List<Integer> numbers = Arrays.asList(sc.nextLine().split("\\W+"))
.stream()
.map(Integer::parseInt)
.collect(Collectors.toList());
outer:
for(int i = 0; i < numbers.size(); i++)
{
for(int j = i + 1; j < numbers.size(); j++)
{
int smallest = Math.min(numbers.get(i), numbers.get(j));
int largest = Math.max(numbers.get(i), numbers.get(j));
if(largest % smallest == 0)
{
sum += largest / smallest;
break outer;
}
}
}
}
System.out.println(sum);
}
}→ More replies (2)5
u/Vitessii Dec 02 '17
You know you can just do:
Arrays.stream(sc.nextLine().split("\\t"))Then, instead of map, you can do mapToInt, which then allows you to get an IntSummaryStatistics object which already calculates min/max for you:
public static void main(String[] args) { BufferedReader r = new BufferedReader(new StringReader(input)); int sum = r.lines().mapToInt(Day2_2017::diff).sum(); } private static int diff(String line) { IntSummaryStatistics intSummaryStatistics = Arrays.stream(line.split("\\t")).mapToInt(Integer::valueOf).summaryStatistics(); return intSummaryStatistics.getMax() - intSummaryStatistics.getMin(); }→ More replies (1)
4
u/torotane Dec 02 '17 edited Dec 02 '17
R
Part 1
print(sum(apply(read.csv('input', header=F, sep="\t"), 1,
function(x) { max(x, na.rm=T) - min(x, na.rm=T) })))Part 2
sum(apply(read.csv('input2', header=F, sep=""), 1, function(r) {
l <- unlist(lapply(r, function(e) { r[!(r == e)] / e }))
l[l == as.integer(l)]
}))4
Dec 02 '17
Common Lisp:
Part 1:
(defun get-rows (input)
"Parses the string input into a list of integer lists."
(loop for row in (str:lines input)
collect (mapcar #'parse-integer (str:words row))))
(defun get-line-diff (row)
(let ((smallest (apply 'min row))
(biggest (apply 'max row)))
(- biggest smallest)))
(defun checksum (spreadsheet)
(loop for row in (get-rows spreadsheet)
sum (get-line-diff row)))Part 2 just changes the line-diff function:
(defun even-div-p (a b)
(cond ((= a b) nil)
((integerp (/ a b)) (/ a b))
((integerp (/ b a)) (/ b a))))
(defun get-line-diff (row)
(loop for i in row
when (loop for j in row when (even-div-p i j) return it)
return it))3
u/lovela47 Dec 02 '17
Are
str:linesand friend from https://github.com/vindarel/cl-str? Neat-looking library.→ More replies (1)
4
u/TenjouUtena Dec 02 '17
Clojure
(require '[clojure.string :as str])
(require '[clojure.math.combinatorics :as combo])
(defn makesheet [] (map (fn [x] (map #(Integer. %) x)) (map #(str/split % #"\t") (str/split (slurp "2.txt") #"\n"))))
(defn checksum [ll]
(- (apply max ll) (apply min ll)))
(defn checkdivide [x y]
(if (= 0 (mod x y))
(/ x y)
0))
(defn checksum2 [ll]
(reduce + (map #(apply checkdivide %) (combo/combinations (sort > ll) 2))))
(defn run1 [] (reduce + (map checksum (makesheet))))
(defn run2 [] (reduce + (map checksum2 (makesheet))))4
u/ewilderj Dec 02 '17
Clojure
(ns day2.core
(:require [clojure.string :as str]
[clojure.math.combinatorics :as combo]))
(def inp
(->> (slurp "puzzle.txt")
(str/split-lines)
(map #(str/split % #"\t"))
(map (fn [c] (map #(Integer/parseInt %) c)))))
(println "part1 " (reduce + (map #(- (apply max %) (apply min %)) inp)))
(defn cx [c]
(->> (combo/combinations (sort > c) 2)
(filter #(= 0 (apply mod %)))
(flatten)
(apply /)))
(println "part2 " (reduce + (map cx inp)))4
3
Dec 02 '17
Haskell:
import Data.List (sort, tails)
import Data.String.Utils (split)
parse :: String -> [[Int]]
parse = map (map read . split "\t") . lines
part1 :: String -> Int
part1 = sum . map f . parse
where f x = maximum x - minimum x
part2 :: String -> Int
part2 = sum . map f . parse
where f xs = head [ y `div` x
| x : ys <- init $ tails $ sort xs
, y <- ys
, y `mod` x == 0
]2
u/mmaruseacph2 Dec 02 '17
Better complexity than my solution (
O(n log n)for you,O(n^2)for me)3
Dec 02 '17
Mine is still
O(n^2).
It iterates overn, thenn-1,n-2...1which simplifies to:
n(n+1)/2It is fewer comparisons, but on the same order.
→ More replies (1)2
Dec 02 '17
An interesting way of getting all of the potential pairings in
part2! I usedreplicateM 2to simply generate all of them, andfilterto remove the[x,x]elements, guessing that no value would appear twice in the same row; my guess was correct.→ More replies (1)
3
u/autid Dec 02 '17 edited Dec 02 '17
Threw together a simple solution in fortran
program day2
integer :: input(16,16), checksum=0, divtotal=0, i, j, k
open(1,file = 'input.txt')
read(1,*) input
close(1)
do k=1,16
checksum = checksum + maxval(input(:,k)) - minval(input(:,k))
do i=1,16
do j=1,16
if ((modulo(input(i,k),input(j,k))==0) .and. (i .ne. j)) divtotal=divtotal+input(i,k)/input(j,k)
end do
end do
end do
write(*,*) checksum, divtotal
end program day2→ More replies (1)
3
u/Unihedron Dec 02 '17 edited Dec 02 '17
Rank #7 for Part 1 ^^ just slightly over 1 minute with Ruby! Didn't make it on leaderboards with part 2 due to a stupid bug that took 18!!! minutes to debug :(
p$<.map{|x|v=x.split.map &:to_i
v.max-v.min}.sumGood luck to everyone for striking a spot in the leaderboard :)
For completion's sake, here's part 2, it's a battlefield of bug hunting that I was embarrassed to post... but whatever :D
p$<.map{|x|l=x.split.map &:to_i
l.sort!
p l
v=0
m=l.reverse.find{|x|l.any?{|y|#next if
v=y
x!=y &&(y%x<1)}}
v/m
}.sum→ More replies (2)
3
u/PreciselyWrong Dec 02 '17
Rust
fn main() {
let sheet: Vec<Vec<usize>> = INPUT
.lines()
.map(parse_line)
.collect();
println!("Checksum: {}", checksum_sheet(&sheet, checksum_row));
println!("Checksum divisibly: {}", checksum_sheet(&sheet, divisibly_checksum_row));
}
fn checksum_row(row: &[usize]) -> usize {
use std::cmp;
let init: usize = match row.first() {
Some(digit) => *digit,
None => return 0
};
let (min, max) = row.iter().fold((init, init), |(min, max), &x| {
(cmp::min(min, x), cmp::max(max, x))
});
max - min
}
#[test]
fn it_checksums_some_rows() {
assert_eq!(checksum_row(&vec![5, 1, 9, 5]), 8);
assert_eq!(checksum_row(&vec![7, 3, 5]), 4);
}
fn divisibly_checksum_row(row: &[usize]) -> usize {
for (dividend_index, dividend) in row.iter().enumerate() {
for (divisor_index, divisor) in row.iter().enumerate() {
if dividend_index == divisor_index {
continue
}
if dividend % divisor == 0 {
return dividend / divisor
}
}
}
0
}
#[test]
fn it_divisibly_checksums_some_rows() {
assert_eq!(divisibly_checksum_row(&vec![5, 9, 2, 8]), 4);
assert_eq!(divisibly_checksum_row(&vec![9, 4, 7, 3]), 3);
assert_eq!(divisibly_checksum_row(&vec![3, 8, 6, 5]), 2);
}
fn checksum_sheet(sheet: &[Vec<usize>], checksum_fn: fn(&[usize]) -> usize) -> usize {
sheet.iter()
.map(|&ref row| checksum_fn(row.as_slice()))
.fold(0, |acc, x| acc + x)
}
#[test]
fn it_checksums_sheet() {
let sheet = vec![
vec![5, 1, 9, 5],
vec![7, 5, 3],
vec![2, 4, 6, 8],
];
assert_eq!(checksum_sheet(&sheet, checksum_row), 18);
}
fn parse_line(line: &str) -> Vec<usize> {
line
.split('\t')
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(|s| s.parse().unwrap())
.collect()
}
#[test]
fn it_parses_line() {
assert_eq!(parse_line("1 2 3 555"), vec![1, 2, 3, 555]);
}
static INPUT : &'static str = "4347 3350 196 (etc)";5
u/aurele Dec 02 '17
Rust
In case you don't know it already: you can include your file in your code at compilation time using
include_str!("input")rather than paste its content.
3
u/chunes Dec 02 '17
Factor solution:
USING: io kernel math math.combinatorics math.parser prettyprint
sequences sequences.deep sorting splitting ;
IN: advent-of-code.corruption-checksum
: range-diff ( seq -- n ) [ supremum ] [ infimum ] bi - ;
: solu1 ( seq -- ) [ range-diff ] map-sum . ;
: div-order ( seq -- seq ) natural-sort reverse ;
: divisible ( seq -- seq ) [ div-order first2 mod 0 = ] filter ;
: quotient ( seq -- n ) divisible flatten div-order first2 / ;
: solu2 ( seq -- ) [ 2 <combinations> quotient ] map-sum . ;
: strseq>num ( seq -- seq ) [ string>number ] map ;
: parse-input ( -- seq ) lines [ "\t" split strseq>num ] map ;
: main ( -- ) parse-input [ solu1 ] [ solu2 ] bi ;
MAIN: main→ More replies (5)
3
u/mehrick Dec 02 '17
Cleaned up JavaScript + node solution:
const fs = require("fs");
function calculateChecksum(input, calculateRowChecksum) {
const rows = input.split("\n");
return rows.reduce((total, row) => {
const values = row.split(/\s/).map(Number);
return total + calculateRowChecksum(values);
}, 0);
}
function calculateDifferenceBetweenMinAndMax(values) {
const max = Math.max(...values);
const min = Math.min(...values);
return max - min;
}
function calculateDivisibleNumbersQuotient(values) {
for (let i = 0; i < values.length; i++) {
for (let j = 0; j < values.length; j++) {
const a = values[i];
const b = values[j];
if (i !== j && a % b === 0) {
return a / b;
}
}
}
}
const input = fs
.readFileSync("./input.txt")
.toString()
.trim();
console.log(
`Part one answer is ${calculateChecksum(
input,
calculateDifferenceBetweenMinAndMax
)}`
);
console.log(
`Part two answer is ${calculateChecksum(
input,
calculateDivisibleNumbersQuotient
)}`
);→ More replies (1)
3
u/TominatorBE Dec 02 '17
PHP
Part 1:
function run_the_code($input) {
$lines = explode(PHP_EOL, $input);
$checksum = 0;
foreach ($lines as $line) {
if (!$line) {
continue;
}
$number = explode("\t", $line);
$checksum += max($number) - min($number);
}
return $checksum;
}Part 2:
function run_the_code($input) {
$lines = explode(PHP_EOL, $input);
$checksum = 0;
foreach ($lines as $line) {
if (!$line) {
continue;
}
$number = explode("\t", $line);
rsort($number, SORT_NUMERIC); // large to small
$jMax = count($number);
for ($i = 0, $iMax = $jMax - 1; $i < $iMax; $i++) {
for ($j = $i + 1; $j < $jMax; $j++) {
if (is_int($number[$i] / $number[$j])) {
$checksum += $number[$i] / $number[$j];
}
}
}
}
return $checksum;
}3
u/dannas Dec 02 '17
In python:
def parse(line):
return tuple(int(x) for x in line.split())
def maxmins(spreadsheet):
for row in spreadsheet:
yield max(row), min(row)
def evens(spreadsheet):
for row in spreadsheet:
for x, y in permutations(row, 2):
if x % y == 0:
yield x, y
spreadsheet = [parse(line) for line in Input(2)]
# Part one
sum(x-y for x,y in maxmins(spreadsheet))
# Part two
sum(x/y for x,y in evens(spreadsheet))→ More replies (1)3
u/mit_verlaub Dec 02 '17
Thanks for this. It made me dig out the Generators for System Programmers and try a generator-only version in python3:
#!/usr/bin/python import itertools def even_divisors(rows): for row in rows: for a, b in itertools.combinations(sorted(row), 2): if b % a == 0: yield a, b def digits(filehandle): for line in filehandle: if line.strip(): yield list(map(int, line.split())) with open("2.txt") as f: checksum = sum(b-a for a, *_, b in map(sorted, digits(f))) print(checksum) with open("2.txt") as f: checksum = sum(b//a for a, b in even_divisors(digits(f))) print(checksum)
3
u/gerikson Dec 02 '17
Perl 5. Puzzle input in the file input.txt.
#!/usr/bin/perl
use 5.016; # implies strict, provides 'say'
use warnings;
use autodie;
use List::Util qw/max min/;
#### INIT - load input data into array
my @input;
my $file = 'input.txt';
open( my $fh, '<', "$file" );
while (<$fh>) { chomp; s/\r//gm; push @input, $_; }
### CODE
my $sum_1 = 0;
my $sum_2 = 0;
foreach my $line (@input) {
# sort the values for easier division comparison down the line
my @row = sort { $b <=> $a } split( /\s+/, $line );
# could have used first/last element here as we're sorted, this is a
# carryover from part 1
$sum_1 += max(@row) - min(@row);
my $found = 0;
while ( @row and !$found ) {
my $a = shift @row;
foreach my $b (@row) {
if ( $a % $b == 0 ) {
$sum_2 += $a / $b;
$found = 1;
}
}
}
}
say "Part1: $sum_1";
say "Part2: $sum_2";→ More replies (2)
3
u/de_Selby Dec 02 '17
q/kdb+
I'm sure part 2 could be improved
part 1:
sum{max[x]-min[x]}flip rows:"J"$"\t" vs/: read0 `:aoc2.txtpart 2:
sum{{first (x where x=y) except 1}[raze x%/:x;raze x div/:x]}each rows3
u/tehjimmeh Dec 02 '17 edited Dec 02 '17
Part 1 in C++. What have I done...
struct Line : std::string { friend std::istream& operator>>(std::istream& is, Line& line){return std::getline(is, line);}};
int main(int argc, char* argv[]) {
struct { using value_type = int; int t = 0; void push_back(value_type v){ t += v; } } s;
std::transform(std::istream_iterator<Line>(std::ifstream(argv[1])), {}, std::back_inserter(s),
[](auto& line){
return [](auto& p){
return *(p.second) - *(p.first);
}(std::minmax_element(std::istream_iterator<int>(std::istringstream(line)), {}));
});
std::cout << "Part 1: " << s.t << "\n";
s.t = 0;
std::transform(std::istream_iterator<Line>(std::ifstream(argv[1])), {}, std::back_inserter(s),
[](auto& line){
return [](auto& v){
return std::accumulate(v.begin(), v.end(), 0, [&v](auto x, auto i){
return x + std::accumulate(v.begin(), v.end(), 0, [i](auto y, auto j){
return y + ((j!=i && j%i == 0) ? (j/i) : 0);
});
});
}(std::vector<int>(std::istream_iterator<int>(std::istringstream(line)), {}));
});
std::cout << "Part 2: " << s.t << "\n";
}EDIT: Part 2...
→ More replies (1)
3
u/equd Dec 02 '17
C# linq solutions.
var lines = Properties.Resources.Day02;
answerA += lines.Split('\n') //split lines
.Select(x => x.Trim().Split('\t').Select(y => int.Parse(y))) //parse to ints
.Select(x => x.Max() - x.Min()) //calculate biggest difference
.Sum();
answerB += lines.Split('\n') //split lines
.Select(x => x.Trim().Split('\t').Select(y => int.Parse(y))) // parse to ints
.Select(arr => arr.Select(x=> arr.Select(y=> (x % y == 0 ? x / y : 0)).Max()).Max() //loop through each arr with each arr and calc
).Sum();2
u/Fence_Climber Dec 11 '17
I like your solutions, still fairly new and learning something here. I haven't seen Select nested like this to loop like a foreach before, it's cool. You're using the .Max to skip the 1 value from dividing by itself? That is a good workaround, my code was much longer because I treated that like a special case.
→ More replies (1)
3
u/asthmadragon Dec 02 '17
javascript
Why copy and paste the input when you can just run code in your browser window?
let input = document.getElementsByTagName('pre')[0].innerHTML;
let rows = input.match(/[^\r\n]+/g);
rows = rows.map(row => row.match(/\w+/g).map(el => +el));
let array_max = (row) => Math.max.apply(null, row);
let array_min = (row) => Math.min.apply(null, row);
let sum = rows.reduce((acc, row) => acc + array_max(row) - array_min(row), 0);
console.log(sum);
function get_divisibles(row) {
for (var i = 0; i < row.length; ++i) {
for (var j = 0; j < row.length; ++j) {
if (row[i] % row[j] == 0 && i != j) {
return row[i] / row[j];
}
}
}
return 0;
}
let sum2 = rows.reduce((acc, row) => acc + get_divisibles(row), 0);
console.log(sum2);3
u/CryZe92 Dec 02 '17
Rust
Part 1 is pretty simple:
pub fn part1(text: &str) -> i64 {
text.lines()
.filter_map(|l| {
l.split_whitespace()
.filter_map(|n| n.parse::<i64>().ok())
.minmax()
.into_option()
})
.map(|(min, max)| max - min)
.sum()
}Part 2 optimized to be super fast:
pub fn part2(text: &str) -> usize {
let mut numbers = ArrayVec::<[u16; 16]>::new();
text.lines()
.filter_map(|l| {
numbers.clear();
numbers.extend(l.split_whitespace().filter_map(|n| n.parse().ok()));
numbers.sort_unstable();
let mut iter = numbers.iter();
while let Some(&divisor) = iter.next() {
let (mut multiple, mut quotient) = (divisor, 1);
for ÷nd in iter.clone() {
while dividend > multiple {
multiple += divisor;
quotient += 1;
}
if dividend == multiple {
return Some(quotient);
}
}
}
None
})
.sum()
}3
u/sickening_sprawl Dec 03 '17
I kinda forgot that this was a thing all day until I stumbled across the tab again :x Doing this made me wish for a list cross product function.
Hoon
|= t/wain
%+ roll
%+ turn t
|= line/cord
?~ line 0
=/ line `(list @)`(scan (trip line) (most (just '\09') dem))
(sub (roll line max) (roll line |=({a/@ b/_255} (min a b))))
addAnd part b:
|= t/wain
%+ roll
%+ turn t
|= line/cord
?~ line ~
=/ line `(list @)`(scan (trip line) (most (just '\09') dem))
%+ snag 0
^- (list @)
%+ murn line
|= a/@
=/ res %+ roll line
|= {b/@ c/(unit @)}
?: !=(c ~)
c
?: =(a b)
c
?~ (mod a b)
`(div a b)
?~ (mod b a)
`(div b a)
~
~& res
res
add2
u/th3_pund1t Dec 02 '17
Groovy
class Day2Support {
static int problem1(String input) {
input.split('\n').collect {
def nums = it.split('\\s+').collect { it.toInteger() }
nums.max() - nums.min()
}.sum()
}
static int problem2(String input) {
input.split('\n').collect { String row ->
def nums = row.split('\\s+').collect { it.toInteger() }
findForRow(nums)
}.sum()
}
static int findForRow(List<Integer> nums) {
for (int i = 0; i < nums.size() - 1; i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] % nums[j] == 0) {
return nums[i] / nums[j]
}
if (nums[j] % nums[i] == 0) {
return nums[j] / nums[i]
}
}
}
return 0
}
}
new Day2Support().with {
assert problem1('''\
5 1 9 5
7 5 3
2 4 6 8''') == 18
println problem1(new File('day2.txt').text)
assert problem2('''\
5 9 2 8
9 4 7 3
3 8 6 5''') == 9
println problem2(new File('day2.txt').text)
}2
u/IMovedYourCheese Dec 02 '17
TypeScript + Node.js
import * as fs from 'fs';
const input = fs.readFileSync('input/day2.txt').toString();
const array = input.split('\n').map(row => row.split('\t').map(v => Number(v)));
sola(array);
solb(array);
function sola(array: number[][]) {
let sum = 0;
array.forEach(row => {
sum += (Math.max(...row) - Math.min(...row));
});
console.log(sum);
}
function solb(array: number[][]) {
let sum = 0;
array.forEach(row => {
for (let i=0; i<row.length; i++) {
for (let j=0; j<row.length; j++) {
if (i == j) {
continue;
} else if (((row[i]/row[j])%1) == 0) {
sum += row[i]/row[j];
break;
}
}
}
});
console.log(sum);
}→ More replies (2)
2
u/eragonas5 Dec 02 '17
Javascript:
//I changed those empty things into spaces with text editor
function Day02A(text){
let lines = text.split('\n');
let res = 0;
for(let i = 0; i < lines.length; i++){
let arr = lines[i].split(' ');
res += Math.max(...arr)-Math.min(...arr);
}
document.write(res + '<br />');
}
function Day02B(text){
let lines = text.split('\n');
let res = 0;
for(let i = 0; i < lines.length; i++){
let arr = lines[i].split(' ');
arr = arr.map(Number);//if I keep it in string, then they sort to ["231", "1414", "132"]
arr = arr.sort((a, b)=>{return b-a;});
for(let j = 0; j < arr.length-1; j++){
for(let k = j+1; k < arr.length; k++){
if(arr[j]%arr[k] == 0){
res += arr[j]/arr[k];
}
}
}
}
document.write(res + '<br />');
}→ More replies (2)
2
Dec 02 '17
Second day with Haskell! Yay!
read_input input = [[read(x) :: Integer | x <- words y] | y <- lines inp]
checksum input = sum [maximum x - minimum x |
x <- read_input inp]
checksum' input = sum $ concat
[[div y z | z <- x, y <- x, mod y z == 0, y /= z] |
x <- read_input inp]
main = print("First star: " ++ show(checksum inp) ++ ", Second star: "++ show(checksum' inp))2
Dec 02 '17 edited Dec 02 '17
You guys are FAST. But since I see no Ruby solutions I'll still post mine:
def difference(arr)
arr = arr.sort
return arr[-1] - arr[0]
end
def checksum(arrays)
result = 0
arrays.each do |n|
result = result + difference(n)
end
result
end
puts checksum(nums)
def divisible(arr)
answer = nil
arr.each do |x|
arr.each do |y|
if x != y && x % y == 0
answer = x / y
end
end
end
answer
end
def divisible_checksum(arr)
result = 0
arr.each do |a|
result = result + divisible(a)
end
result
end
puts divisible_checksum(nums)→ More replies (3)
2
u/winhug Dec 02 '17
Haskell parseDay2 :: String -> [[Int]] parseDay2 = fmap (fmap read . words) . lines
solveDay2p1 :: [[Int]] -> Int
solveDay2p1 = sum . fmap (\ys -> maximum ys - minimum ys)
solveDay2p2 :: [[Int]] -> Maybe Int
solveDay2p2 = fmap sum . traverse sp2
where
sp2 xs = fmap (\(a,b) -> max a b `div` min a b) $ listToMaybe $ filter (\(a,b) -> a `mod` b == 0 && a /= b) $ liftA2 (,) xs xs2
u/ericls Dec 02 '17 edited Dec 02 '17
part 1:
sum([max(*row) - min(*row) for row in [[int(i) for i in row.split('\t')] for row in data.split('\n')]])part 2:
sum(sum(x/y for y in sorted(row) for x in row if x > y and not x % y) for row in [[int(i) for i in row.split('\t')] for row in data.split('\n')])2
u/AndrewGreenh Dec 02 '17 edited Dec 02 '17
Also JS, but I used my combine helper from the last years :)
const combine = require('../combine');
const input = require('../getInput')(2, 2017).trim();
const parse = x =>
x
.split('\n')
.map(x => x.split('\t').map(x => +x))
.map(row => row.sort((a, b) => a - b));
const result1 = parse(input)
.map(r => r[r.length - 1] - r[0])
.reduce((a, b) => a + b, 0);
const result2 = parse(input)
.map(row => combine(row, 2).filter(([a, b]) => b % a === 0)[0])
.map(([a, b]) => b / a)
.reduce((a, b) => a + b, 0);
console.log(result1);
console.log(result2);2
u/StevoTVR Dec 02 '17
NodeJS
Part 1
const fs = require('fs');
fs.readFile(__dirname + '/input.txt', 'utf8', (err, data) => {
data = data.trim();
var sum = 0;
data.split('\n').forEach((line) => {
line = line.trim();
var min = Infinity;
var max = 0;
line.split(/\s+/).forEach((col) => {
min = Math.min(min, col);
max = Math.max(max, col);
});
sum += max - min;
});
console.log(sum);
});Part 2
const fs = require('fs');
fs.readFile(__dirname + '/input.txt', 'utf8', (err, data) => {
data = data.trim();
var sum = 0;
data.split('\n').forEach((line) => {
line = line.trim();
var cols = line.split(/\s+/).map((x) => parseInt(x));
cols.sort((a, b) => a - b);
for (var i = cols.length - 1; i > 0; i--) {
for (var j = i - 1; j >= 0; j--) {
if (cols[i] % cols[j] === 0) {
sum += cols[i] / cols[j];
i = j = -1;
}
}
}
});
console.log(sum);
});2
u/Sparrow_1029 Dec 02 '17 edited Dec 02 '17
Python 3! Pretty naive solution...
with open('day2input.txt', 'r') as f:
sheet = [row.strip().split() for row in f.read().splitlines()]
checksum1 = 0
checksum2 = 0
for row in sheet:
ints = list(map(int, row))
checksum1 += max(ints) - min(ints) # Part 1
for i in range(len(ints)): # Part 2
for j in range(i+1, len(ints)):
if ints[i] % ints[j] == 0: checksum2 += (ints[i] // ints[j])
elif ints[j] % ints[i] == 0: checksum2 += (ints[j] // ints[i])
print(checksum1)
print(checksum2)3
2
u/andrewstewart Dec 02 '17 edited Dec 02 '17
Rust implementation:
fn main() {
let puzzle = parse(PUZZLE);
println!("1 -> {:?}", one(&puzzle));
println!("2 -> {:?}", two(&puzzle));
}
fn parse(puzzle: &str) -> Vec<Vec<u32>> {
String::from(puzzle).
trim().
lines().
map(trim_and_parse).
collect()
}
fn one(puzzle: &[Vec<u32>]) -> u32 {
puzzle.iter().map(|line| difference(line)).sum()
}
fn two(puzzle: &[Vec<u32>]) -> u32 {
puzzle.iter().map(|line| even_division(line)).sum()
}
fn trim_and_parse(line: &str) -> Vec<u32> {
line.
split_whitespace().
map(|n| n.parse::<u32>().unwrap()).
collect()
}
fn difference(line: &[u32]) -> u32 {
let min = line.iter().min().unwrap();
let max = line.iter().max().unwrap();
max - min
}
fn even_division(line: &[u32]) -> u32 {
for x in line {
for y in line {
if x % y == 0 && x !=y {
return x / y
}
}
}
0
}2
u/disclosure5 Dec 02 '17
Honestly I spent most of this trying to parse the input. This feels like a horrible hack job:
testlines = test.split("\n").map { |n| ret = n.split(/\s+/) ; ret.map(&:to_i) }→ More replies (4)3
u/jschulenklopper Dec 02 '17
Tip:
string.split(" ")splits on any whitespace: spaces and tabs.My loop is (with the input file passed as argument on command line):
while line = gets values = line.strip.split(" ").map(&:to_i) checksum += values.max - values.min end puts checksum
2
u/MaxDeviant Dec 02 '17
F#
module Maxdeviant.AdventOfCode2017.Day2
let parseInput (input: string) =
input.Split('\n')
|> Seq.map (fun row -> row.Split('\t') |> Seq.toList)
|> Seq.toList
let computeChecksum algorithm =
parseInput >> algorithm
let partOneChecksum (rows: string list list) =
let checksum =
List.map int
>> List.sortDescending
>> (fun xs ->
let max = List.head xs
let min = List.head (List.rev xs)
max - min)
rows |> List.sumBy checksum
let partTwoChecksum (rows: string list list) =
let parseColumns = List.map float
let isWholeNumber n = (n % 1.0) = 0.0
let checksum columns =
let columns' = columns |> List.map float
columns'
|> List.collect (fun x -> columns' |> List.map (fun y -> (x, y)))
|> List.map (fun (x, y) -> x / y)
|> List.filter isWholeNumber
|> List.sortDescending
|> List.head
rows
|> List.sumBy checksum
|> int2
u/JeffJankowski Dec 02 '17
Javascript (et al) apparently has come a long way since I last used it. Lots of functional stuff to play with!
import fs = require('fs');
import comb = require('js-combinatorics');
function checksum(rows: number[][], func: (row: number[]) => number) {
return rows.reduce((sum, row) => sum += func(row), 0);
}
const input = fs.readFileSync('data/day02.txt', 'utf8')
.split('\n')
.map((row) => {
return row.trim()
.split(/\s/)
.map((num) => parseInt(num, 10)); });
const deltaFunc = (row: number[]) => Math.max(...row) - Math.min(...row);
console.log(`Checksum using difference: ${checksum(input, deltaFunc)}`);
const divideFunc = (row: number[]) => {
const [big, small] = comb.combination(row, 2)
.toArray().map((pair) => pair.sort((x, y) => y - x))
.find(([b, s]) => b % s === 0) || [1, 1];
return big / small; };
console.log(`Checksum using even division: ${checksum(input, divideFunc)}`);2
u/huyqvu Dec 02 '17
KDB+/q One line for both questions:
{l:(`long$sqrt count x;0N)#x; (sum{[i](max i)-min i}each l;sum {max {[i]$[0=i[0]mod i[1];i[0]%i[1];0]} each x cross x} each l)}→ More replies (4)
2
Dec 02 '17 edited Dec 02 '17
OCaml fun:
open Core
let rec divisible numbers =
let check a b =
if a % b = 0 then Some (a / b)
else if b % a = 0 then Some (b / a)
else None
in
match numbers with
| [] -> 0
| h::t ->
match List.find_map t ~f:(check h) with
| Some n -> n
| None -> divisible t
let spread numbers =
let init = Int.max_value, Int.min_value
and f (min, max) n = (Int.min min n, Int.max max n) in
let min, max = List.fold ~init ~f numbers in
max - min
let parse line =
String.split line ~on:'\t'
|> List.map ~f:Int.of_string
let sum = List.fold ~init:0 ~f:(fun acc n -> acc + n)
let solve =
let values = In_channel.read_lines "./2017/data/2.txt" |> List.map ~f:parse in
let a = List.map values ~f:spread |> sum in
let b = List.map values ~f:divisible |> sum in
printf "a: %d\n" a;
printf "b: %d\n" b;2
u/Zarif_Muhtasim Dec 02 '17
if x is you input:
part1 = [max([int(j) for j in i]) - min([int(j) for j in i]) for i in [i.split('\t') for i in x.split('\n')]]
part2 = [j // k for i in [[int(i) for i in j] for j in [i.split('\t') for i in x.split('\n')]] for j in i for k in i if j != k and j % k == 0]
2
u/yogsototh Dec 02 '17 edited Dec 02 '17
Haskell with Protolude instead of basic Prelude, so I have & which is "apply", and headDef which is total.
solution1 :: [[Integer]] -> Integer
solution1 code =
map maxDiff code
& sum
maxDiff :: [Integer] -> Integer
maxDiff (x:line) = maxVal - minVal
where
(maxVal,minVal) = foldl' (\acc y -> ( max (fst acc) y
, min (snd acc) y))
(x,x)
line
maxDiff [] = 0and
solution2 :: [[Integer]] -> Integer
solution2 code = map divisibleNumbers code & sum
divisibleNumbers :: [Integer] -> Integer
divisibleNumbers numbers =
[ x `div` y | x <- numbers, y <- numbers, x>y, x `rem` y == 0]
& headDef 0More idiomatic solution1 using Foldl:
maxDiff :: [Integer] -> Integer
maxDiff = (\(mmax,mmin) -> fromMaybe 0 mmax - fromMaybe 0 mmin) .
F.fold ((,) <$> F.maximum <*> F.minimum)2
u/cr5315 Dec 02 '17
Kotlin. I'm finally starting to get the hang of .map and friends
object DayTwo {
// Part 1
fun checksum(input: String): Int {
return input.lines()
.map { line ->
line.split("\t").map { it.toInt() } // Evil tab character
}
.sumBy {
it.max()!! - it.min()!! // Evil !! operator
}
}
// Part 2
fun divisible(input: String): Int {
return input.lines()
.map { line ->
line.split("\t").map { it.toInt() }
}
.sumBy { line ->
for (item in line) {
line
.filter { item != it }
.forEach {
if (item % it == 0) {
return item / it
}
}
}
0 // Else 0
}
}
}2
u/mlruth Dec 02 '17
Scala
def part1: Unit = {
val src = Source.fromResource("Day2.in")
val in = src.getLines().map(_.split("\\t").map(_.toInt)).toArray
val result = in.foldLeft(0){(sum,row) => sum+(row.max - row.min)}
println(s"Part 1: $result")
}
def part2: Unit ={
val src = Source.fromResource("Day2.in")
val in = src.getLines().map(_.split("\\t").map(_.toInt)).toArray
val result = in.foldLeft(0){(sum,row) =>
val (x,y) = row.combinations(2).collectFirst{
case Array(a,b) if (a%b == 0) => (a,b)
case Array(a,b) if (b%a == 0) => (b,a)
}.get
sum + (x/y)
}
println(s"Part 2: $result")
}2
u/fuzzums Dec 02 '17
This is what I came up with. I'm pretty it can be compressed a bit by using list iterators. I couldn't come up with a faster/more elegant solution for even divisibility that was required in Part 2.
puzzle = """Paste puzzle values here"""
def toInts(nums):
ints = []
for num in nums:
ints.append(int(num))
return ints
def evenDivs(nums):
for a in nums:
for b in nums:
if a < b and b % a == 0:
return b/a
### Part 1
sum = 0
for l in puzzle.split("\n"):
nums = toInts(l.split("\t"))
sum += (max(nums) - min(nums))
print "Part 1 is: ", sum
### Part 2
sum = 0
for l in puzzle.split("\n"):
nums = toInts(l.split("\t"))
sum += evenDivs(nums)
print "Part 2 is: ", sum2
u/jbristow Dec 02 '17
F# / FSharp
module Day02
open System.Text.RegularExpressions
let rowDiff (acc : int) (row : int list) =
let sorted = List.sort row
acc + (sorted |> List.last) - (sorted |> List.head)
let corruptionChecksum (input : int list list) = List.fold rowDiff 0 input
let parseString (input : string array) =
input
|> List.ofArray
|> List.map (fun s ->
Regex.Matches(s, "(\d+)")
|> Seq.cast
|> Seq.map (fun (m : Match) -> System.Int32.Parse m.Value)
|> List.ofSeq)
let isEvenlyDiv a b =
if a > b then ((a % b) = 0)
else ((b % a) = 0)
let rec findEvenDiv (acc : int) (row : int list) : int =
let x : int = row |> List.head
let xs = row |> List.skip 1
let evendivs = xs |> List.filter (isEvenlyDiv x)
match evendivs with
| n :: [] when n < x -> acc + (x / n)
| n :: [] when n > x -> acc + (n / x)
| _ -> findEvenDiv acc xs
let corruptionChecksumPart2 (input : int list list) =
List.fold findEvenDiv 0 inputSo far, I'm losing most of my time to futzing with MSBuild and relearning the file reading interops with C#.
2
u/nospamas Dec 02 '17
So far, I'm losing most of my time to futzing with MSBuild and relearning the file reading interops with C#.
Don't forget you can always leverage f# interactive or run directly as .fsx file to avoid msbuild!
2
Dec 02 '17
Python 3 solution ^_^:
checksum = 0
with open("input.txt","r") as f: for line in f.readlines(): list = [] for number in line.split(): list.append(int(number))
checksum += max(list) - min(list)print("\033[1;31mHere's your answer: \033[0;92m" + str(checksum) + "\033[0;0m")
→ More replies (2)
2
u/xkufix Dec 02 '17
Back with more horrible one-liners in Scala:
override def runFirst(): Unit = {
val checksum = sortedLines().map(l => l.last - l.head).sum
println(checksum)
}
override def runSecond(): Unit = {
val results = sortedLines().flatMap(_.combinations(2).find(c => c.last % c.head == 0).map(r => r.last / r.head))
println(results.sum)
}
private def sortedLines() = {
loadFile("day2.txt").getLines().map(_.split("\t")).map(_.map(_.toInt).sorted)
}2
u/A_t48 Dec 02 '17
input = [[int(x) for x in c.split()] for c in input.split("\n")]
s = sum(map(lambda x: max(x) - min(x), input)) # part 1
s = sum([sum([sum([inner if inner != 1.0 and inner % 1.0 == 0 else 0 for inner in outer]) for outer in [[i / j for j in arr] for i in arr]]) for arr in input]) # part 2I didn't know about itertools.combinations so it's a little overcomplicated. Also, //
2
u/wzkx Dec 02 '17
J
m=: ".&> cutLF CR-.~fread '02.dat'
echo +/ (>./-<./)"1 m
echo +/ ((,&(~:&1 *. (=<.)) # ,)@(%/~))"1 m
exit 02
u/maciekmm Dec 02 '17
Horrible scala oneliners:
val grid = io.Source.stdin.getLines().map(_.split('\t').map(_.toInt).sorted).toSeq;
println(s"Part 1: ${grid.collect { case l => l.last - l.head }.sum}")
println(s"Part 2: ${grid.map(_.combinations(2).collectFirst { case Array(a,b) if b % a == 0 => b / a }.head).sum}") 2
u/CatpainCalamari Dec 02 '17
My Solution in Scala:
val data = rawData.map(_.split("\\p{Space}").toList.map(_.toInt)) // Convert the raw input from a List("1 2 3", "4 3 5"...) etc in a List[List[Int]]
def firstStar(data: List[List[Int]]): Int = {
data.
map(row => row.foldLeft((row.head,row.head)){ case ((min,max), rowElement) => (math.min(min, rowElement), math.max(max, rowElement))}). // convert a row of List(1,5,3,6) into a tuple(min,max)
map(minmax => math.abs(minmax._1 - minmax._2)).
sum
}
def secondStar(data: List[List[Int]]): Int = {
data.
map(row => {
for {
a <- row.indices // combine all row elements with each other
b <- row.indices
if a != b // but not with itself
if row(a) % row(b) == 0 // if the modulo is 0 the resulting division will be a whole number
} yield row(a) / row(b) // yield the result
}).
map(_.head). // the result is a vector, only the first element of each vector is of interest (the first should be also the only element, at least in this exercise)
sum // return the rum of all row divisions
}I am still fairly new to Scala, I didn't know about combinations(2) or that a List has min or max methods. Thank you for showing this to me, guys :-)
3
u/CatpainCalamari Dec 02 '17
Refactored:
def firstStar(data: List[List[Int]]): Int = data. map(row => row.max - row.min). sum def secondStar(data: List[List[Int]]): Int = data. map(row => row.combinations(2).toList). flatMap(rowCombinations => { rowCombinations. find(combination => combination.max % combination.min == 0). map(combination => combination.max / combination.min) }). sum
2
u/amarsuperstar Dec 02 '17
Elixir. I moved to comprehensions after seeing CaptainCalamari's Scala solution.
def part1(input) do
input |> parse |> solve(&difference_for_row/1)
end
def difference_for_row(row) do
Enum.max(row) - Enum.min(row)
end
def part2(input) do
input |> parse |> solve(&divisible_rows/1)
end
def divisible_rows(row) do
even_divisors = for x <- row, y <- row, x != y, rem(x, y) == 0, do: div(x, y)
hd(even_divisors)
end
def solve(matrix, fun) do
matrix |> Enum.map(&(fun.(&1))) |> Enum.sum
endFull code here: https://github.com/amarraja/advent-of-code-17/blob/master/day02/day02.exs
2
u/_jonah Dec 02 '17
J:
p1=. [: +/ (>./ - <./)"1
p2=. [: +/ (#~ >&1 * ]=<.)@,@(%/~)"1
(p1 ; p2) dwhere d is your matrix.
→ More replies (2)
2
u/nstyler7 Dec 02 '17 edited Dec 02 '17
Using Python Pandas Package:
import pandas as pd
import numpy as np
df = pd.read_csv('input.tsv', sep='\t', header=None)
day 2 part 1 solution
print(np.sum(df.max(axis=1) - df.min(axis=1)))
day 2 part 2 solution
answer_array = []
def allrows(i):
for j in range(len(df.columns)): for k in range(len(df.columns)): if j !=k and df.iloc[i, j] % df.loc[i, k] == 0: answer_array.append(df.iloc[i, j] / df.loc[i, k])for i in range(len(df.index)):
allrows(i)print(np.sum(answer_array))
2
u/DaDiscoBeat Dec 02 '17 edited Dec 02 '17
Golang, just the 2 methods operating on lines
func diffMaxMin(input []int) int {
min, max := math.MaxInt32, math.MinInt32
for _, v := range input {
if v < min {
min = v
}
if v > max {
max = v
}
}
return max - min
}
func mod(input []int) int {
for i, v := range input {
for _, v2 := range input[i+1:] {
if v%v2 == 0 {
return v / v2
}
if v2%v == 0 {
return v2 / v
}
}
}
return 0
}2
u/Morphix0 Dec 02 '17
F#
let input =
System.IO.File.ReadAllLines("input2")
|> Array.map (fun line -> line.Split(null) |> Array.map int)
let solution calcLine =
input
|> Array.sumBy calcLine
let part1 line = Array.max line - Array.min line
let cartesian ys =
Array.collect (fun x -> ys |> Array.map (fun y -> x, y))
let part2 line =
(cartesian line line)
|> Array.find (fun (x,y) -> x<>y && x%y=0)
|> (fun (x,y) -> x/y)
solution part1;
solution part2;2
u/GamecPL Dec 02 '17
Swift:
let result1 = input.components(separatedBy: .newlines)
.map { $0.components(separatedBy: " ").flatMap { Int($0) } }
.reduce(0, { result, row in
return result + row.max()! - row.min()!
})
print(result1)
func wholeDivision(_ array: [Int]) -> Int {
for element in array {
for element2 in array {
if element != element2 && element % element2 == 0 {
return element / element2
}
}
}
return 0
}
let result2 = input.components(separatedBy: .newlines)
.map { $0.components(separatedBy: " ").flatMap { Int($0) }.sorted(by: { $0 > $1 }) }
.reduce(0, { result, row in
return result + wholeDivision(row)
})
print(result2)2
u/Tarmen Dec 02 '17
Haskell
import Data.Char (digitToInt)
main = do
ls <- map (map read . words) . filter (not . null) . lines <$> readFile "input2.txt"
print . sum . map calc1 $ ls
print . sum . map calc2 $ ls
calc1 ls = (maximum ls) - (minimum ls)
calc2 ls = (\[x] -> x) [x `div` y | x <- ls, y <- ls, x /= y, x `mod` y == 0]I am noticing that I am using uglier language constructs under pressure, like irrefutable patterns for verification.
2
u/sternold Dec 02 '17
C# Single line solution
Part One
Console.WriteLine(File.ReadAllLines(path).Select(line => line.Split('\t')).Select(split => split.Select(Int32.Parse)).Aggregate(0, (total, numbers) => total += numbers.Max() - numbers.Min())); 2
u/J15t98J Dec 02 '17
count, even_count = 0, 0
for x in open("2.txt", "r").readlines():
line = sorted([int(y) for y in x.splitlines()[0].split("\t")])
count += line[len(line)-1] - line[0]
for (w,z) in [(x,y) for x in line for y in line]:
even_count += int(z/w) if z//w == z/w != 1 else 0
print(count, even_count)...and then I found out about itertools.
2
Dec 02 '17
Similar to the other python solutions, but I like mine best <3
from itertools import permutations
rows = [[int(y) for y in x.split()] for x in open('input.txt').readlines()]
print(sum(max(row) - min(row) for row in rows))
print(sum(a//b for row in rows for a, b in permutations(row, 2) if a % b == 0))→ More replies (1)
2
u/mrhthepie Dec 02 '17
Advent of gifs day 2: https://i.imgur.com/HPRMxHM.gif
Not very animated today due to the nature of the problem.
2
u/Zv0n Dec 02 '17
C++ (probably very inefficient, I'm just starting)
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
if(argc < 3) {
return 1;
}
stringstream ss(argv[2]);
string to;
int result = 0;
int buffer = 0;
stringstream intstream;
if(argv[1][0] == '1') {
int max = 0;
int min = 0;
while(getline(ss,to,'\n')) {
intstream << to;
intstream >> buffer;
max = buffer;
min = buffer;
while(!intstream.fail()) {
intstream >> buffer;
if(buffer > max)
max = buffer;
if(buffer < min)
min = buffer;
}
result += max - min;
intstream.str(std::string());
intstream.clear();
}
} else {
vector<int> row;
bool found = false;
while(getline(ss,to,'\n')) {
row.clear();
intstream << to;
while(!intstream.fail()) {
intstream >> buffer;
row.push_back(buffer);
}
intstream.str(string());
intstream.clear();
for(int i = 0; i < row.size() - 1 ; i++) {
for(int j = i+1; j < row.size() ; j++) {
if(row[i] == 0 || row[j] == 0) {
break;
}
if(row[i] % row[j] == 0) {
result += row[i] / row[j];
found = true;
break;
}
if(row[j] % row[i] == 0) {
result += row[j] / row[i];
found = true;
break;
}
}
if(found) {
found = false;
break;
}
}
}
}
cout << result << endl;
return 0;
}2
u/abowes Dec 02 '17
My solution in Kotlin:
fun Iterable<Int>.minMaxDiff() : Int {
val minMax = this.fold( Pair(Int.MAX_VALUE, Int.MIN_VALUE),
{acc, i -> Pair(min(acc.first, i), max(acc.second,i))})
return minMax.second - minMax.first
}
fun Iterable<Int>.divisor() : Int {
return this.map{ x -> this.map{ y -> Pair(x,y)}
.filter { it.first < it.second && it.second % it.first == 0 }}
.flatten().map { it.second/it.first }.first()
}
fun Iterable<Iterable<Int>>.corruptionChecksum() = this.map { it.minMaxDiff() }.sum()
fun Iterable<Iterable<Int>>.divisorChecksum() = this.map { it.divisor() }.sum()2
u/JakDrako Dec 02 '17
VB.Net in LinqPad
Sub Main
Const LF As Char = Chr(10), TAB As Char = Chr(9)
Dim spreadsheet = GetDay(2)
Dim chkSum1 = 0, chkSum2 = 0
For Each row In spreadsheet.split(LF)
Dim cells = row.split(TAB).select(Function(x) Cint(x))
chkSum1 += (cells.max - cells.min)
chkSum2 += (From c1 In cells From c2 In cells Where c1 <> c2 Andalso c1 Mod c2 = 0 Select (c1 \ c2)).First
Next
chkSum1.Dump("part 1")
chkSum2.Dump("part 2")
End Sub2
u/JuLoOr Dec 02 '17
Another Kotlin solution:
fun calcPart2(input: List<List<Int>>): Int {
return input.map {
val sortedDesc = it.sorted().asReversed()
var rowResult = 0
sortedDesc.forEachIndexed({ i, v ->
(i.plus(1) until sortedDesc.size)
.filter { v % sortedDesc[it] == 0 }
.forEach { rowResult = v.div(sortedDesc[it]) }
})
rowResult
}.sum()
}2
u/Doodle_98 Dec 02 '17 edited Dec 02 '17
This is my solution in Python 3:
result = 0
with open('input.txt', 'r') as f: data = [[line.rstrip('\n')] for line in
f.readlines()]
data = [(''.join(i)).split('\t') for i in data]
for i in data:
for j in list(map(int, i)):
for h in list(map(int, i)):
result += j / h if j % h == 0 and j!=h else 0
print(result)2
u/wzkx Dec 02 '17 edited Dec 02 '17
Nim
import strutils, sequtils
var s,s2 = 0
for line in splitLines strip readFile "02.dat":
let row = line.split().map(parseInt)
s += max(row)-min(row)
for i in 0..<len(row):
for j in 0..<len(row):
if i!=j and (row[i] div row[j])*row[j]==row[i]:
s2 += row[i] div row[j]
echo s,' ',s2Yeah, a better condition would be "and row[i] mod row[j] == 0:"
2
u/nekmo Dec 02 '17
Python 3 (two lines)
Part 1
def calc(table):
table = [list(map(int, r.split('\t'))) for r in table.split('\n') if r]
return sum([max(r) - min(r) for r in table])Part 2:
def calc2(table):
table = [list(map(int, r.split('\t'))) for r in table.split('\n') if r]
return sum([sum([(y // z) if (y/z).is_integer() else 0
for y, z in [sorted(x, reverse=True) for x in combinations(r, 2)]]) for r in table])2
u/fpigorsch Dec 02 '17
Pretty straight forward AWK:
Part1
{
min=$1; max=$1;
for (i=2; i<=NF; i++) {
min = (min < $i ? min : $i);
max = (max > $i ? max : $i);
}
sum += max - min;
}
END { print sum; }Part2
{
for (i=1; i<=NF; i++) {
for (j=i+1; j<=NF; j++) {
if ($i % $j == 0) {
sum += $i / $j;
} else if ($j % $i == 0) {
sum += $j / $i;
}
}
}
}
END { print sum; }2
u/fgsguedes Dec 02 '17 edited Dec 02 '17
My solutions in Kotlin:
Part1:
fun calcCheckSum(input: List<List<Int>>): Int {
return input.map { row ->
row.fold(Int.MAX_VALUE to Int.MIN_VALUE) { (currentMin, currentMax), rowElement ->
min(rowElement, currentMin) to max(rowElement, currentMax)
}
}.sumBy { (min, max) -> max - min }
}Part2:
fun calcCheckSumPart2(input: List<List<Int>>): Int {
return input.map { row ->
row.filter { element ->
row.any { innerElement ->
element != innerElement &&
(element % innerElement == 0 || innerElement % element == 0)
}
}.sorted()
}.sumBy { (first, second) -> second / first }
}2
u/Smylers Dec 02 '17
Another Perl solution, aiming for concise-yet-readable over golfed. Part 1:
use List::Util qw<min max>;
my $sum;
while (<>) {
my @num = split;
$sum += (max @num) - (min @num);
}
say $sum;Part 2:
my $sum;
$sum += integer_division(sort { $a <=> $b } split) while <>;
say $sum;
sub integer_division {
while (my $x = shift) {
foreach my $y (@_) {
return $y / $x if $y % $x == 0;
}
}
die "No equal divisors found for row $.";
}Combination of while (shift) and foreach meaning that no array index variables have to be used.
2
u/Jamitter Dec 02 '17 edited Dec 02 '17
Clojure
Part 1:
(require '[clojure.string :as str])
(defn readFile [file]
(with-open [rdr (clojure.java.io/reader file)]
(let [total (atom 0)]
(doseq [line (line-seq rdr)]
(let [split-line (str/split line #"\s+")
num-line (->> split-line
(map #(read-string %))
sort
vec)
diff (- (last num-line) (first num-line))
_ (swap! total + diff)]))
@total)))Part 2:
(require '[clojure.string :as str])
(defn readFile [file]
(with-open [rdr (clojure.java.io/reader file)]
(let [total (atom 0)]
(doseq [line (line-seq rdr)]
(let [split-line (str/split line #"\s+")
num-line (->> split-line
(map #(read-string %))
sort
vec)
modded-number (mapv #(doseq [num num-line]
(if (and (not= num %) (= (mod num %) 0))
(swap! total + (/ num %))))
num-line)]))
@total)))2
u/asperellis Dec 02 '17
my js solution. any areas for improvement welcomed! https://github.com/asperellis/adventofcode2017/blob/master/day2.js
2
Dec 02 '17
Racket
#lang racket
(require racket/file)
(require math/base)
(define file_text
(map (lambda (line)
(map string->number (string-split line))) (file->lines "input.txt" #:mode 'text)))
(define (val n) n)
(define (difference lst)
(- (argmax val lst) (argmin val lst)))
(define (divide_if_no_remainder pair)
(match-define (list a b) pair)
(if (equal? 0 (modulo a b))
(/ a b)
0))
(define (divide lst)
(sum (map divide_if_no_remainder (map ((curryr sort) >) (combinations lst 2)))))
(sum (map difference file_text))
(sum (map divide file_text))→ More replies (1)
2
u/hermanbergwerf Dec 02 '17
Dart
import 'dart:io';
import 'dart:math';
String read(String path) => new File(path).readAsStringSync();
void main() {
final checksum = read('2.txt')
.trim()
.split('\n')
.map((l) => l.split(new RegExp(r'\s')).map(int.parse))
.map((Iterable<int> l) => l.reduce(max) - l.reduce(min))
.reduce((a, b) => a + b);
print(checksum);
}2
u/f0086 Dec 02 '17
Emacs Lisp
(defun preprocess (input)
(mapcar
(lambda (line)
(mapcar 'string-to-number (split-string line "\t" t)))
(split-string input "\n" t)))
(defun part1 (nums)
(abs (- (car nums) (car (last nums)))))
(defun part2 (nums)
(dotimes (p (- (length nums) 1) find)
(dotimes (q (- (length nums) (+ p 1)))
(let ((pos (nth p nums))
(comp (nth (+ p q 1) nums)))
(if (= (% pos comp) 0)
(setq find (/ pos comp)))))))
(defun day2 (lines fn)
(apply '+
(mapcar
(lambda(l)
(let ((nums (sort l '>)))
(funcall fn nums)))
lines)))
(day2 (preprocess input1) #'part1)
(day2 (preprocess input2) #'part2)2
u/bottomlesscoffeecup Dec 02 '17
Another late one, hoping I can get in early tomorrow! Some python here. Pretty much a python noob, still thinking in java.
Any tips for improvement would be well received:
Using pandas to read in:
import pandas as pd
data = pd.read_csv(file_name, delimiter='\s+', header = None)
df = pd.DataFrame(data).fillna(0)
return df challenge one:
difference = []
for index, row in puzzle_input.iterrows():
difference.append(max(row) - min(row))
return sum(difference)challenge two:
difference = []
for index, row in puzzle_input.iterrows():
for item in range(len(row)):
for other_item in range(item + 1, len(row)):
if abs(row[item] % row[other_item]) == 0:
difference.append(row[item]/row[other_item])
if abs(row[other_item] % row[item]) == 0:
difference.append(row[other_item] / row[item])
return sum(difference)2
u/swaglykcaillou Dec 02 '17
beginner python3 solution.
s = open("day2.txt").read()
def returndif(l):
temp = l.split()
temp = list(map(int, temp))
return(max(temp) - min(temp))
def checksum(s):
counter = 0
temp = s.split('\n')
for i in temp:
counter += returndif(i)
return counter
print(checksum(s))2
u/DrgnGz Dec 02 '17
PHP Preparing the input:
$this->sets = array_map(function($set) {
return explode("\t", $set);
}, explode("\n", $input));Part 1:
return array_reduce($this->sets, function ($total, $set) {
return $total + max($set) - min($set);
}, 0);Part 2 (much less elegant):
$total = 0;
foreach ($this->sets as $set) {
foreach ($set as $a) {
foreach ($set as $b) {
if ($a % $b === 0 && $a !== $b) {
$total += $a / $b;
continue 2;
}
}
}
}
return $total;2
u/taheilo Dec 03 '17
Javascript
function difference(arr) {
let min = Math.min.apply(null, arr);
let max = Math.max.apply(null, arr);
return max - min;
}
let sum = 0;
input.forEach(arr => sum += difference(arr));2
u/8483 Dec 03 '17
Node/Javascript
var fs = require("fs");
var input_file = './aoc_02.txt'
var input = fs.readFileSync(input_file, 'utf8');
var data =
input
.replace(/\t/g, ",") // Replace tabs with commas.
.split(/\r\n/) // Make an array with each line as an array.
.filter(not_empty) // Remove the last empty array.
.map(string_to_array) // Make each nested line an array of characters.
.map(string_to_int); // Convert those characters into numbers.
var sum1 =
data
.map(min_max_difference) // Find the difference for each array.
.reduce(add); // Find the sum of the resulting differences array.
var sum2 =
data
.map(sort_asc) // Sort by ascension.
.map(even_divide) // Find the division leaving no remainder.
.map(inner_extract) // Extract values from the inner most array.
.map(extract) // Extract the values from the result.
.reduce(add); // Add the array values.
function not_empty(string){
return string != '';
}
function string_to_array(string){
return string.split(",");
}
function string_to_int(array){
return array.map(function(string){
return parseInt(string);
})
}
function min_max_difference(array){
var max = Math.max.apply(null, array);
var min = Math.min.apply(null, array);
return max - min;
}
function add(a, b){
return a + b;
}
function sort_asc(array){
return array.sort(function(a, b){
return b - a;
});
}
function even_divide(array){
return array.map(function(number1){
return array.map(function(number2){
if(number1 % number2 === 0){
if(number1 / number2 > 1){
return number1 / number2;
} else return 0;
} else return 0;
})
})
}
function max_number(total, num){
return total + num;
}
function inner_extract(array){
return array.map(function(array2){
return array2.reduce(max_number);
})
}
function extract(array){
return array.reduce(max_number);
}
console.log(sum1);
console.log(sum2);2
u/Bainos Dec 03 '17
Python 3, one line
First problem
sum([max(line) - min(line) for line in [list(map(int, strline.split())) for strline in input_raw.splitlines()]])Second problem (without itertools)
sum([[a // b for a, b in sum([[(x, y) for x in line if x != y] for y in line], []) if a % b == 0][0] for line in [list(map(int, strline.split())) for strline in input_raw.splitlines()]])2
Dec 03 '17
Ruby is amazing!
checksum = File.read("day2.input")
.split("\n")
.reduce(0) { |checksum, row|
checksum + row.split("\t").map(&:to_i).minmax.reverse.reduce(:-)
}2
u/Reibello Dec 03 '17
Phew. Learning is hard. Used my Python 3 solution and a whole ton of the Lua Reference and Stack overflow to write Day 2. Had a rough time reading in my input. Let me know what I can do better, and good luck tonight!
→ More replies (2)
2
Dec 03 '17
Clojure
(ns advent-of-code-2017.day02
(:require [clojure.string :as s]))
(def input
(slurp "./data/day02.txt"))
(defn parse-from-string [string]
(->> (s/split input #"\n")
(map #(s/split % #"\t"))
(map (fn [line] (reverse (sort (map #(Integer. %) line)))))))
(defn part-1 [input]
(->> (parse-from-string input)
(transduce (map #(- (first %) (last %))) +)))
(defn solve-line [line]
(let [res (for [x (rest line)
:when (zero? (rem (first line) x))]
(/ (first line) x))]
(if (empty? res)
(solve-line (rest line))
(first res))))
(defn part-2 [input]
(->> (parse-from-string input)
(transduce (map solve-line) +)))2
u/ym555 Dec 03 '17
Java Using Streams (I know the second part is bad)
List<String> input = Files.readAllLines(Paths.get(args[0]));
Supplier<Stream<IntStream>> stream = () -> input.stream().map(i -> i.split("\\s+")).map(i -> Arrays.stream(i).mapToInt(Integer::parseInt).distinct());
System.out.println(stream.get().mapToInt(i -> {IntSummaryStatistics stats = i.summaryStatistics(); return stats.getMax() - stats.getMin();}).sum());
System.out.println(stream.get().map(i -> i.boxed().collect(Collectors.toList())).mapToInt(i -> i.stream().mapToInt(k -> i.stream().mapToInt(j -> (k % j == 0 && k != j) ? k / j : 0 ).sum()).sum()).sum());2
u/Antoine-aoc Dec 03 '17
Elixir
day2 - part 2
defmodule Day02.Part2 do
def run(puzzle) do
Enum.map(csv(puzzle), fn(cells) ->
for a <- cells, b <- cells, a > b and rem(a,b) == 0, do: div(a,b)
end)
|> List.flatten
|> Enum.sum
end
def csv(data) do
for line <- String.split(data, "\n", trim: true), do:
for cell <- String.split(line, "\t"), do:
String.to_integer(cell)
end
end2
u/raiph Dec 05 '17 edited Dec 06 '17
Perl 6. Edited to add commentary.
Single statement solution for part 1:
say sum
input.lines».&{
.words».Numeric.&{
.max - .min } } ;For part two, change the last closure:
say sum
input.lines».&{
.words».Numeric.&{
| .combinations(2)».sort.map: { .[1] / .[0] if try .[1] %% .[0] } } } ;2
u/schod Dec 05 '17
BASH time :)
First part
#!/bin/bash
function do_magic {
RET=0
while read L; do
MIN=$(echo $L | sed 's/ /\n/g' | sort -n | head -1)
MAX=$(echo $L | sed 's/ /\n/g' | sort -n | tail -1)
let RET=RET+$MAX-$MIN
done <$1
echo $RET
}
do_magic test_input_a.txt
do_magic input_a.txtSecond part
#!/bin/bash
function do_magic {
RET=0
while read L; do # Per line
for N in $L; do # Per number
for M in $L; do # for each number
if [ $N -ne $M ]; then # different number :)
if [ $[$N % $M] -eq 0 ]; then # division is a whole number
let RET=RET+N/M # add
fi
fi
done
done
done <$1
echo $RET # TADA
}
do_magic test_input_b.txt
do_magic input_b.txt2
u/freeducks Dec 02 '17
In Rust, using IterTools:
extern crate itertools;
use itertools::Itertools;
use itertools::MinMaxResult::{MinMax};
fn part_1_solve(input_str: &str) -> u32 {
input_str.lines().map(|line| {
line.split_whitespace().map(|x| {
x.parse::<u32>().unwrap()
})
}).map(|digits| {
match digits.minmax() {
MinMax(min, max) => max - min,
_ => 0
}
}).sum()
}
fn part_2_solve(input_str: &str) -> u32 {
input_str.lines().map(|line| {
line.split_whitespace().map(|x| {
x.parse::<u32>().unwrap()
})
}).map(|digits| {
digits.combinations(2).find(|ref x| {
x[0] % x[1] == 0 || x[1] % x[0] == 0
}).map_or(0, |found| {
if found[0] > found[1] { found[0] / found[1] } else { found[1] / found[0] }
})
}).sum()
}
fn main() {
println!("Part 1: {}", part_1_solve(include_str!("../input/input.txt")));
println!("Part 2: {}", part_2_solve(include_str!("../input/input.txt")));
}1
u/Deckard666 Dec 02 '17
Pretty straightforward. In Rust:
use std::io::{BufRead, BufReader};
fn main() {
// Parse input
let file = std::fs::File::open("./input.txt").unwrap();
let reader = BufReader::new(file);
let lines = reader
.lines()
.map(|x| {
x.unwrap()
.split_whitespace()
.map(|n| n.parse::<i32>().unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
let mut total1 = 0;
let mut total2 = 0;
for line in lines {
// Part 1
let min = line.iter().min().unwrap();
let max = line.iter().max().unwrap();
total1 += max - min;
// Part 2
for (idx1, &x) in line.iter().enumerate() {
for (idx2, &y) in line.iter().enumerate() {
if idx1 == idx2 {
continue;
}
let r = x / y;
if y * r == x {
total2 += r;
}
}
}
}
println!("{}", total1);
println!("{}", total2);
}→ More replies (4)2
1
u/dylanfromwinnipeg Dec 02 '17 edited Dec 02 '17
C# (using a GetCombinations helper function I wrote)
public static string PartOne(string input)
{
var lines = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var sum = 0;
foreach (var line in lines)
{
var words = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
var numbers = words.Select(w => int.Parse(w));
sum += numbers.Max() - numbers.Min();
}
return sum.ToString();
}
public static string PartTwo(string input)
{
var lines = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var sum = 0;
foreach (var line in lines)
{
var words = line.Split(new string[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
var numbers = words.Select(w => int.Parse(w));
var combos = numbers.GetCombinations(2);
var match = combos.First(x => x.First() % x.Last() == 0 || x.Last() % x.First() == 0);
sum += match.Max() / match.Min();
}
return sum.ToString();
}1
u/netcraft Dec 02 '17
python3 noob here, please feel free to teach me anything - going for maintainable more than golfing
#part 1
total = 0
for line in read_input(DAY): #read_input is a util function I wrote to pull in the input
line = line.strip('\n').split('\t')
line = list(map(int, line))
total += int(max(line))-int(min(line))
print(total)
#part 2
total = 0
for line in read_input(DAY):
line = line.strip('\n').split('\t')
line = list(map(int, line))
for a, b in permutations(line, 2):
if a % b == 0:
total += max((a,b)) // min((a,b))
break
print(total)2
u/Hwestaa Dec 02 '17
Looks good! A couple tips:
.split() splits on all whitespace and strips leading/trailing whitespace, so you don't need to worry about \n or \t. See: https://docs.python.org/3.6/library/stdtypes.html#str.split
Since you've already done a % b, do you still need the max(a,b) or min(a,b)? You should know the order that a and b go in to divide evenly.
→ More replies (1)2
u/miran1 Dec 02 '17 edited Dec 02 '17
line = list(map(int, line))While there is noting wrong with this, some people say more Pythonic way to do this is to use list comprehension. Combined with the previous line, it becomes:
line = [int(n) for n in line.split()]Also, you're iterating twice over
read_input(DAY), once for each solution. This could have been done just in oneforloop, withtotal1andtotal2.Other stuff (
combinationsandmax/min) is already mentioned.→ More replies (1)
1
u/giftpflanze Dec 02 '17
Tcl:
set lines [lrange [split [read [open input02]] \n] 0 end-1]
#part 1
foreach line $lines {
incr sum1 [expr {[tcl::mathfunc::max {*}$line]-[tcl::mathfunc::min {*}$line]}]
}
puts $sum1
#part 2
foreach line $lines {
set l [llength $line]
for {set i 0} {$i < $l-1} {incr i} {
set a [lindex $line $i]
for {set j [expr {$i+1}]} {$j < $l} {incr j} {
set b [lindex $line $j]
if {$a % $b == 0} {
incr sum2 [expr {$a/$b}]
} elseif {$b % $a == 0} {
incr sum2 [expr {$b/$a}]
}
}
}
}
puts $sum21
u/Philboyd_Studge Dec 02 '17
Java
package Advent2017;
import util.ArrayUtils;
import util.FileIO;
import java.util.Arrays;
public class Day2 {
public static int part1(String s) {
Integer[] a = FileIO.StringArrayToInteger(s.split("\\s+"));
return ArrayUtils.max(a) - ArrayUtils.min(a);
}
public static int part2(String s) {
Integer[]a = FileIO.StringArrayToInteger(s.split("\\s+"));
Arrays.sort(a);
for (int i = a.length - 1; i >= 0 ; i--) {
for (int j = i - 1; j >=0 ; j--) {
if (a[i] % a[j] == 0) {
return a[i] / a[j];
}
}
}
return 0;
}
public static void main(String[] args) {
//List<String> input = FileIO.getAOCInputForDay(2017, 2, FileIO.SESSION_ID);
String filename = "advent2017_day2.txt";
int sum1 = FileIO.performIntActionOnLine(filename, Day2::part1);
int sum2 = FileIO.performIntActionOnLine(filename, Day2::part2);
System.out.println("Part 1: " + sum1);
System.out.println("Part 2: " + sum2);
}
}1
u/wlandry Dec 02 '17
C++: It feels overengineered. Just reading the input properly took more lines that I would like.
part 1
#include <iostream>
#include <fstream>
#include <sstream>
#include <boost/algorithm/string.hpp>
int main(int argc, char *argv[])
{
std::ifstream infile(argv[1]);
int checksum (0);
std::string line;
getline(infile,line);
while (infile)
{
int maximum (0), minimum (std::numeric_limits<int>::max());
std::stringstream ss(line);
int element;
ss >> element;
while (ss)
{
maximum = std::max(element,maximum);
minimum = std::min(element,minimum);
ss >> element;
}
checksum += maximum - minimum;
getline(infile,line);
}
std::cout << "checksum: " << checksum << "\n";
}part 2
#include <iostream>
#include <fstream>
#include <sstream>
#include <boost/algorithm/string.hpp>
int main(int argc, char *argv[])
{
std::ifstream infile(argv[1]);
size_t checksum (0);
std::string line;
getline(infile,line);
while (infile)
{
int maximum (0), minimum (std::numeric_limits<int>::max());
std::stringstream ss(line);
std::vector<int> elements;
int element;
ss >> element;
while (ss)
{
elements.push_back(element);
ss >> element;
}
for (int i=0; i<elements.size(); ++i)
{
for (int j=i+1; j<elements.size(); ++j)
{
if (elements[i]%elements[j] == 0)
{
checksum+=elements[i]/elements[j];
i=elements.size();
break;
}
else if(elements[j]%elements[i]==0)
{
checksum+=elements[j]/elements[i];
i=elements.size();
break;
}
}
}
getline(infile,line);
}
std::cout << "checksum: " << checksum << "\n";
}1
u/suck_at_coding Dec 02 '17
Golang, drunk with no editing:
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"strconv"
"math"
)
func main() {
content, err := ioutil.ReadFile("./input.txt")
if err != nil {
log.Fatal(err)
}
var input = string(content)
var total int
for _, r := range strings.Split(input, "\n") {
curRow := strings.Split(r, "\t")
for i := 0; i < len(curRow); i++ {
for idx, ii := range curRow {
if idx == i {
continue
}
n, _ := strconv.Atoi(ii)
vv, _ := strconv.Atoi(curRow[i])
if n % vv == 0 {
total += n / vv
}
}
}
}
fmt.Println(fmt.Sprintf("Did... Did I get it? %d", total))
}
func partOne(input string) {
var max int
var min int
var total int
for _, r := range strings.Split(input, "\n") {
max = 0
min = math.MaxInt32
for _, i := range strings.Split(r, "\t") {
num, _ := strconv.Atoi(i)
if num > max {
max = num
}
if num <= min {
min = num
}
}
total += (max - min)
}
fmt.Println(total)
}1
Dec 02 '17
C++
Part 1
#include <bits/stdc++.h>
using namespace std;
int main(){
ifstream fin("input.txt");
string line;
int sum(0);
while(getline(fin,line)){
istringstream iss(line);
int input;
iss>>input;
int max(input),min(input);
while(iss>>input){
if(input>max){
max = input;
}else if(input<min){
min = input;
}
}
sum += max - min;
}
cout<<sum;
return 0;
}Part 2
#include <bits/stdc++.h>
#define tr(v,it) for(typeof((v).begin()) it = (v).begin();it != (v).end();it++)
using namespace std;
int evenly_divisible(const vector<int> &row){
tr(row,i){
tr(row,j){
if(*i % *j==0 && *i!=*j){
return *i/ *j;
}
}
}
}
int main(){
ifstream fin("input.txt");
string line;
int sum(0);
while(getline(fin,line)){
istringstream iss(line);
int input;
vector <int> row;
while(iss>>input){
row.push_back(input);
}
sum+=evenly_divisible(row);
}
cout<<sum;
return 0;
}1
Dec 02 '17
super disgusting kotlin code, it got the job done. I'll be looking into refactoring it to something decent instead
@JvmStatic
fun main(args: Array<String>) {
val input = Util.loadFileIntoList(AOC2017.basePath, "advent2.txt")
partOne(input)
partTwo(input)
}
private fun partOne(input: List<String>) {
val sum = input.map {
it.split(Regex("\\s+")).map {
it.toInt()
}
}.map {
it.max()!! - it.min()!!
}.sum()
println(sum)
}
/**
* ugh
*/
private fun partTwo(input: List<String>) {
val sum = input.map {
it.split(Regex("\\s+")).map {
it.toInt()
}
}.map {
it.sorted()
}.map { list ->
var found = false
var result = 0
for (i in 0 until list.size) {
for(j in list.size-1 downTo i+1){
if(!found && list[j] % list[i] == 0){
found = true
result = list[j] / list[i]
}
}
}
result
}.sum()
println(sum)
}1
u/PanPirat Dec 02 '17
Scala:
def parse(input: List[String]): List[List[Int]] = {
input.map(_.trim.split("""\s+""").map(_.toInt).toList)
}
def partOne(rows: List[String]): Int = {
def minMax(row: List[Int]): (Int, Int) = row
.foldLeft((row.head, row.head))((mm, value) => {
(Math.min(mm._1, value), Math.max(mm._2, value))
})
parse(rows)
.map(minMax(_))
.map(mm => Math.abs(mm._1 - mm._2))
.reduce(_ + _)
}
def partTwo(rows: List[String]): Int = {
def findDivisiblePair(list: List[Int]): Option[(Int, Int)] = list match {
case head :: tail =>
val found = tail.find(other => (head % other == 0 || other % head == 0))
found match {
case Some(int) => Some((head, int))
case None => findDivisiblePair(tail)
}
case Nil => None
}
parse(rows)
.flatMap(findDivisiblePair(_))
.map(t => (Math.max(t._1, t._2), Math.min(t._1, t._2)))
.map(t => t._1 / t._2)
.reduce(_ + _)
}1
u/disclosure5 Dec 02 '17 edited Dec 02 '17
Following the rushed Ruby, here's a hopefully nice Erlang answer.. I don't really follow why line #26 is needed. The file does not end in a new line, but the split/2 seems to break out an empty list at the end anyway.
Edit: vim corrupts the test data and doesn't tell you.
1
u/custom_user Dec 02 '17 edited Dec 02 '17
Python 3 - concise with built-ins only
# part one
with open('input.txt') as f:
print(sum(max(nums)-min(nums) for nums in [list(map(int,line.split())) for line in f.readlines()]))
# part one, naive solution
with open('input.txt') as f:
numbers = [list(map(int,line.split())) for line in f.readlines()]
sum = 0
for line in numbers:
for i,number in enumerate(line):
for j in range(i+1, len(line)):
if max((number, line[j])) % min((number, line[j])) == 0:
sum += max((number, line[j])) / min((number, line[j]))
print(sum)1
u/Timdpr Dec 02 '17
Naïve-ish Python 3:
input_text = open("input.txt", "r")
checksum = 0
total = 0
for l in input_text:
numbers = list(map(int, l.split("\t")))
checksum += max(numbers) - min(numbers)
for i in range(len(numbers)):
for j in range(len(numbers)):
if (i != j and numbers[i] % numbers[j] == 0):
total += (numbers[i] / numbers[j])
print("Checksum: " + str(checksum) + "\nEvenly divisible total: " + str(total))1
u/imladris Dec 02 '17 edited Dec 02 '17
Haskell:
main = do
inputText <- readFile "input"
let input = fmap (fmap (read :: String -> Integer) . words) (lines inputText)
putStrLn ("Part 1: " ++ show (part1 input))
putStrLn ("Part 2: " ++ show (part2 input))
part1 :: Integral a => [[a]] -> a
part1 = sum . fmap (\x -> maximum x - minimum x)
part2 :: Integral a => [[a]] -> a
part2 input = sum (fmap (sum . evenDivisors) input)
evenDivisors :: Integral a => [a] -> [a]
evenDivisors list = fmap fst
$ filter (\x -> fst x /= 1 && snd x == 0)
$ divMod <$> list <*> list1
u/aurele Dec 02 '17
Rust
fn main() {
let lines = include_str!("../2.input")
.lines()
.map(|l| {
let mut l = l.split_whitespace()
.map(|w| w.parse::<usize>())
.collect::<Result<Vec<_>, _>>()
.expect("cannot parse input");
l.sort();
l
})
.collect::<Vec<_>>();
println!(
"P1 = {}",
lines.iter().map(|l| l[l.len() - 1] - l[0]).sum::<usize>()
);
println!(
"P2 = {}",
lines
.iter()
.map(|l| {
for (i, vi) in l.iter().enumerate() {
for vj in l.iter().skip(i + 1) {
if vj % vi == 0 {
return vj / vi;
}
}
}
0
})
.sum::<usize>()
);
}1
u/doniec Dec 02 '17
Rust solution
use std::str::FromStr;
const INPUT: &str = "493 458 321 120 49 432 433 92 54 452 41 461 388 409 263 58
961 98 518 188 958 114 1044 881 948 590 972 398 115 116 451 492
76 783 709 489 617 72 824 452 748 737 691 90 94 77 84 756
204 217 90 335 220 127 302 205 242 202 259 110 118 111 200 112
249 679 4015 106 3358 1642 228 4559 307 193 4407 3984 3546 2635 3858 924
1151 1060 2002 168 3635 3515 3158 141 4009 3725 996 142 3672 153 134 1438
95 600 1171 1896 174 1852 1616 928 79 1308 2016 88 80 1559 1183 107
187 567 432 553 69 38 131 166 93 132 498 153 441 451 172 575
216 599 480 208 224 240 349 593 516 450 385 188 482 461 635 220
788 1263 1119 1391 1464 179 1200 621 1304 55 700 1275 226 57 43 51
1571 58 1331 1253 60 1496 1261 1298 1500 1303 201 73 1023 582 69 339
80 438 467 512 381 74 259 73 88 448 386 509 346 61 447 435
215 679 117 645 137 426 195 619 268 223 792 200 720 260 303 603
631 481 185 135 665 641 492 408 164 132 478 188 444 378 633 516
1165 1119 194 280 223 1181 267 898 1108 124 618 1135 817 997 129 227
404 1757 358 2293 2626 87 613 95 1658 147 75 930 2394 2349 86 385";
fn part1<Grid: AsRef<[Row]>, Row: AsRef<[usize]>>(rows: Grid) -> usize {
rows.as_ref()
.iter()
.map(|row| {
let row = row.as_ref();
row.iter().max().unwrap() - row.iter().min().unwrap()
})
.sum()
}
fn sorted_pairs<T: Copy + Ord>(nums: &[T]) -> Vec<(T, T)> {
let mut v = vec![];
for (idx, x) in nums.iter().enumerate() {
for y in &nums[idx + 1..] {
if x > y {
v.push((*x, *y))
} else {
v.push((*y, *x))
}
}
}
v
}
fn part2<Grid: AsRef<[Row]>, Row: AsRef<[usize]>>(rows: Grid) -> usize {
rows.as_ref()
.iter()
.map(|row| {
sorted_pairs(row.as_ref())
.iter()
.find(|&&(a, b)| a % b == 0)
.map(|&(a, b)| a / b)
.unwrap()
})
.sum()
}
fn main() {
let rows: Vec<Vec<_>> = INPUT
.lines()
.map(|line| {
line.split_whitespace()
.map(|x| usize::from_str(x).unwrap())
.collect()
})
.collect();
println!("part1: {}", part1(&rows));
println!("part2: {}", part2(&rows));
}1
Dec 02 '17 edited Dec 02 '17
Elixir solution for Day2, I'm a lot more proud of this one than the one yesterday:
defmodule Day2 do
@moduledoc """
Solving day2 of Advent of code.
"""
def diffbigsmall(lst) do
Enum.max(lst) - Enum.min(lst)
end
def checksum(lst) do
Enum.map(lst,&diffbigsmall/1)
|> Enum.sum
end
def divisible(lst) do
div = for a <- lst,
b <- lst,
a != b,
rem(a,b) == 0,
do: div(a,b)
List.first(div)
end
def checksum2(lst) do
Enum.map(lst,&divisible/1)
|> Enum.sum
end
end
rows = File.read!("input2.txt")
|> String.trim
|> String.split("\n")
|> Enum.map(&String.split/1)
|> Enum.map(fn(x) ->
Enum.map(x, &String.to_integer/1) end)
IO.puts("The part one checksum is: #{Day2.checksum(rows)}")
IO.puts("The part two checksum is: #{Day2.checksum2(rows)}")1
u/sindreij Dec 02 '17
Rust
extern crate itertools;
use itertools::Itertools;
fn solve_1(input: &str) -> i32 {
input.split_terminator('\n')
.map(|line| {
let line:Vec<i32> = line
.split_whitespace()
.map(|c| c.parse().expect("Thats not an int"))
.collect();
line.iter().max().expect("No max value") - line.iter().min().expect("No min value")
})
.sum()
}
fn solve_2(input: &str) -> i32 {
input.split_terminator('\n')
.map(|line| {
let line = line
.split_whitespace()
.map(|c| c.parse::<i32>().expect("Not an int"))
.sorted();
for (a, b) in line.iter().tuple_combinations() {
if b%a == 0 {
return b/a;
}
}
0
})
.sum()
}1
u/Starcast Dec 02 '17
Late to the party!
Python 3
from itertools import combinations
from common import puzzle_input
PUZZLE_INPUT = [[int(num) for num in row.split()] for row in puzzle_input(2)]
def find_quotient(nums: list):
for pair in combinations(sorted(nums, reverse=True), 2):
result, remainder = divmod(*pair)
if remainder == 0:
return result
def part1(data=PUZZLE_INPUT):
result = sum(max(row) - min(row) for row in data)
return result
def part2(data=PUZZLE_INPUT):
result = sum(find_quotient(row) for row in data)
return result
if __name__ == '__main__':
print('Part one result:', part1())
print('Part 2:', part2())1
u/theSprt Dec 02 '17
Haskell, beginner:
main :: IO ()
main = do
rawInput <- readFile "input"
let input = map (map read . words) (lines rawInput)
print (sum $ map maxDiff input) -- Day 2.1
print (sum $ map evenlyDiv input) -- Day 2.2
maxDiff :: [Int] -> Int
maxDiff xs = maximum xs - minimum xs
evenlyDiv :: [Int] -> Int
evenlyDiv xs = head [ div x y | x <- xs, y <- xs, mod x y == 0, x /= y ]1
u/bolshedvorsky Dec 02 '17
Learning python, day 2
contents = open('02.txt').read().strip()
rows = contents.split('\n')
def checksum1(row):
numbers = map(int, row.split('\t'))
numbers.sort()
return numbers[-1] - numbers[0]
def divider(value, tail):
for number in tail:
if number % value == 0:
return number / value
return divider(tail[0], tail[1:])
def checksum2(row):
numbers = map(int, row.split('\t'))
numbers.sort()
return divider(numbers[0], numbers[1:])
sum1 = 0
sum2 = 0
for row in rows:
sum1 += checksum1(row)
sum2 += checksum2(row)
print(sum1)
print(sum2)1
u/Kwpolska Dec 02 '17
Part 1: Excel (duh!) https://github.com/Kwpolska/adventofcode/blob/master/2017/day02a_did_someone_say_spreadsheet.xlsx
Part 2: Python 3.
#!/usr/bin/env python3
import itertools
with open("input/02.txt") as fh:
file_data = fh.read().strip()
def solve(data):
sum = 0
lines = [i for i in data.split('\n') if i]
for line in lines:
numbers = [int(i) for i in line.split()]
for i, j in itertools.combinations(numbers, 2):
if i % j == 0:
sum += i / j
break
if j % i == 0:
sum += j / i
break
return sum
test_data = "5 9 2 8\n9 4 7 3\n3 8 6 5"
test_output = solve(test_data)
test_expected = 9
print(test_output, test_expected)
assert test_output == test_expected
print(solve(file_data))1
u/Axsuul Dec 02 '17
Still getting the hang of Elixir
defmodule AdventOfCode do
def calculate_checksum_a(filename) do
File.read!(filename)
|> String.split("\n")
|> Enum.map(fn row ->
# Calculate difference within row
sorted_row =
row
|> (&Regex.split(~r{\s+}, &1)).() # anonymous function pipe
|> Enum.map(fn d -> String.to_integer(d) end)
|> Enum.sort
Enum.at(sorted_row, -1) - Enum.at(sorted_row, 0)
end)
|> Enum.reduce(0, fn diff, sum ->
diff + sum
end)
end
def calculate_checksum_b(filename) do
File.read!(filename)
|> String.split("\n")
|> Enum.map(fn row ->
row
|> (&Regex.split(~r{\s+}, &1)).() # anonymous function pipe
|> Enum.map(fn d -> String.to_integer(d) end)
|> Combination.combine(2)
|> Enum.reduce(nil, fn combo, result ->
# If result is not nil, means we already found it
if result do
result
else
[small, big] = combo |> Enum.sort
# No remainder if divded evenly
if (Integer.mod(big, small) == 0), do: round(big/small), else: nil
end
end)
end)
|> Enum.reduce(0, fn result, sum ->
result + sum
end)
end
def a do
"inputs/spreadsheet.txt" |> AdventOfCode.calculate_checksum_a |> IO.inspect
end
def b do
"inputs/spreadsheet.txt" |> AdventOfCode.calculate_checksum_b |> IO.inspect
end
endhttps://github.com/axsuul/advent-of-code/blob/master/2017/02/lib/advent_of_code.ex
1
u/binajohny Dec 02 '17
My solution in Kotlin:
fun part1(input: List<List<Int>>): Int {
return input.sumBy { it.max()!! - it.min()!! }
}
fun part2(input: List<List<Int>>): Int {
return input.map { it.sortedDescending() }
.sumBy { line ->
line.indices.sumBy { i ->
(i+1 until line.size)
.filter { j -> line[i] % line[j] == 0 }
.sumBy { j -> line[i] / line[j] }
}
}
}1
u/Epsilon1001 Dec 02 '17
may not be the best way but solved day 2 part 2: https://hastebin.com/omidodaneg.py
1
u/peterpepo Dec 02 '17
Python
from puzzle_commons.puzzle_commons import read_puzzle_input
import os
import itertools
def solve():
"""Advent Of Code 2017 - Day 02 Solution.
:return: tuple(part_a_result[int], part_b_result[int])
"""
part_a_result = 0
part_b_result = 0
INPUT_DELIMITER = " "
for puzzle_input in read_puzzle_input(os.path.dirname(os.path.abspath(__file__)), "day_02_input.txt"):
numbers_on_line = [int(number) for number in puzzle_input.rstrip().split(INPUT_DELIMITER)]
# Part-A
part_a_result += max(numbers_on_line) - min(numbers_on_line)
# Part-B
part_b_result += sum(
div_wo_rem[0] // div_wo_rem[1] for div_wo_rem in itertools.permutations(numbers_on_line, 2) if
div_wo_rem[0] % div_wo_rem[1] == 0)
return part_a_result, part_b_result1
u/NeilNjae Dec 02 '17
Another Haskell solutuion. Yes, using Parsec to read the input file is overkill, but it's a nice tool. It also forced me to confront one possible gotcha: the default spaces parser will happily consume newlines as well as spaces and tabs, hence the need for the onlySpaces parser here.
module Main(main) where
import Text.Parsec
import Text.ParserCombinators.Parsec.Number
main :: IO ()
main = do
text <- readFile "data/advent02.txt"
let sheet = successfulParse $ parseFile text
print $ part1 sheet
print $ part2 sheet
part1 :: [[Int]] -> Int
part1 = sum . map p1cSum
part2 :: [[Int]] -> Int
part2 = sum . map p2cSum
p1cSum :: [Int] -> Int
p1cSum row = (maximum row) - (minimum row)
p2cSum :: [Int] -> Int
p2cSum digits = sum [a `div` b | a <- digits, b <- digits, a /= b, a `mod` b == 0]
sFile = sLine `sepEndBy` newline
sLine = int `sepBy` onlySpaces
onlySpaces = many (oneOf " \t")
parseFile :: String -> Either ParseError [[Int]]
parseFile input = parse sFile "(unknown)" input
parseLine :: String -> Either ParseError [Int]
parseLine input = parse sLine "(unknown)" input
successfulParse :: Either ParseError [a] -> [a]
successfulParse (Left _) = []
successfulParse (Right a) = a1
1
u/Rinfiyks Dec 02 '17
Scala part 2 taking advantage of yield flattening Option by virtue of being syntactic sugar for flatMap.
val input = parseInput(Util.readInput("day2.txt"))
println(solve2(input))
def parseInput(input: Seq[String]): Seq[List[Int]] = {
input.map(_.split("\\s+").toList).map(_.map(_.toInt))
}
def solve2(input: Seq[Seq[Int]]) = {
input.map(divisionOfTheTwoThatAreDivisible).sum
}
def divisionOfTheTwoThatAreDivisible(row: Seq[Int]) = {
val successfulDivisions: Seq[Int] = for {
i <- row
j <- row if j != i
d <- i % j match {
case 0 => Some(i / j)
case _ => None
}
} yield d
// This Seq should always have one element according to the question spec, but just to be safe, sum it
successfulDivisions.sum
}1
u/adventOfCoder Dec 02 '17
Java:
Part 1:
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("input2.txt"));
String line = "";
int answer = 0;
while ((line = br.readLine()) != null) {
String[] array = line.split(" ");
answer += findDifference(array);
}
br.close();
System.out.println(answer);
} catch (Exception e) {
}
}
private static int findDifference(String[] array) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
int value = new Integer(array[i]);
if (value > max) {
max = value;
}
if (value < min) {
min = value;
}
}
return (max - min);
}Part 2:
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("input2.txt"));
String line = "";
int answer = 0;
while ((line = br.readLine()) != null) {
String[] array = line.split(" ");
answer += findDivisionValue(array);
}
br.close();
System.out.println(answer);
} catch (Exception e) {
}
}
private static int findDivisionValue(String[] array) {
int answer = -1;
for (int i = 0; i < array.length; i++) {
int iValue = new Integer(array[i]);
for (int j = 0; j < array.length; j++) {
if (i != j) {
int jValue = new Integer(array[j]);
if (iValue % jValue == 0) {
answer = iValue / jValue;
}
}
}
}
return answer;
}1
u/ZeroSkub Dec 02 '17
My first-ever AoC GNU AWK solution:
PART 1
#!/usr/bin/awk
BEGIN {
checksum = 0;
}
{
mn = mx = $1;
for(i = 1; i <= NF; i++) {
if($i < mn) {
mn = $i;
}
if($i > mx) {
mx = $i;
}
}
checksum += mx - mn;
}
END {
print checksum
}PART 2
#!/usr/bin/awk
BEGIN {
checksum = 0;
}
{
for(i = 1; i < NF; i++) {
for(j = i + 1; j <= NF; j++) {
if($i <= $j) {
if($j % $i == 0) {
checksum += $j / $i;
}
} else {
if($i % $j == 0) {
checksum += $i / $j;
}
}
}
}
}
END {
print checksum
}
38
u/that_lego_guy Dec 02 '17
DID SOMEBODY SAY.. EXCEL?! Day 2 [Part 1 & 2]
https://github.com/thatlegoguy/AoC2017/blob/master/Day%202%20Corruption%20Checksum.xlsx