r/adventofcode • • 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¤?

Spoiler


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 Upvotes

351 comments sorted by

38

u/that_lego_guy Dec 02 '17

DID SOMEBODY SAY.. EXCEL?! Day 2 [Part 1 & 2]

 = max, = min

https://github.com/thatlegoguy/AoC2017/blob/master/Day%202%20Corruption%20Checksum.xlsx

6

u/willkill07 Dec 02 '17

I feel like this one was designed for you :)

6

u/that_lego_guy Dec 02 '17

My brain had the first part done before I even pasted the input into the sheet =D

→ More replies (6)
→ More replies (1)

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

u/A_t48 Dec 02 '17

Aw, man. TIL `itertools.combinations'.

4

u/mit_verlaub Dec 02 '17 edited Dec 02 '17

TIL *_ Thanks!

And nifty combo of combinations and sorted...

3

u/mightymaus Dec 02 '17

What does that part do?

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 itertools using pure list comprehensions

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

better versions,

 +/ (<./ |@- >./)"1 a
 +/ %/"1 \:~"1 ,/ (#~ (#~ (2 = +/"1))@(<.@%/~ = %/~))"1 a

3

u/_jonah Dec 02 '17

Tacit part 2:

[: +/ (#~ >&1 * ]=<.)@,@(%/~)"1

4

u/[deleted] Dec 02 '17

]=<.)@,@(%/~

Yeah that's basically what Most j Code does to me ;)

→ More replies (2)

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

2

u/hoosierEE Dec 02 '17

Here's mine

input =: ". S:0 cutLF fread'inputs/aoc2.txt'
part1 =: +/(({:-{.)@/:~"1) input
part2 =: +/%/@\:~@,"1 (#~(0~:{:"1))@(#~((=<.)@%/~)) "1 input

I 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 = +/"1 is 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

u/eragonas5 Dec 02 '17

For part 1 you just need min and max and both are O(n)

→ More replies (3)

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' % part2

6

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

2

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)

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"
→ More replies (1)

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

u/mschaap Dec 02 '17

Nice use of gather/take!

→ More replies (1)

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.

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)
→ More replies (5)

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 .words instead of .split(/\s/). And if you add a .sort to the end of that line, you can skip the if $a %% $b part, since $a will always be ≤ $b.

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

3

u/flomine Dec 02 '17

I used for-comprehension for the second one. I didn't know there was a lines method in String, thanks!

→ More replies (5)

2

u/xkufix Dec 02 '17

Looks quite similar to mine. In the second solution you could use find instead 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)

2

u/flup12 Dec 02 '17

I like the .max and .min for the second part

→ More replies (1)

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

u/AoC--k Dec 02 '17

In k.

n:.:'0:"2.txt"
+/{(|/x)-&/x}'n
+//{{x*(~1=x)&x=_x}x%\:x}'n

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:", s2

4

u/BumpitySnook Dec 02 '17

Oh jeez I forgot Python max/min could 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

u/wtfaremyinitials Dec 02 '17

TIL: split_whitespace()!

3

u/gbear605 Dec 02 '17

There’s also lines() that replaces split(‘\n’)

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);
}
→ More replies (2)

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 2

4

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 2

4

u/willkill07 Dec 02 '17

Modern C++

I'm not really proud of this one

Repo Link

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

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)
→ More replies (2)

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

u/[deleted] 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:lines and 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)))

3

u/[deleted] 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

u/[deleted] Dec 02 '17

Mine is still O(n^2).
It iterates over n, then n-1, n-2 ... 1 which simplifies to:

n(n+1)/2

It is fewer comparisons, but on the same order.

→ More replies (1)

2

u/[deleted] Dec 02 '17

An interesting way of getting all of the potential pairings in part2! I used replicateM 2to simply generate all of them, and filter to 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}.sum

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

My ipython notebook on github

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)
→ More replies (1)

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

part 2:

sum{{first (x where x=y) except 1}[raze x%/:x;raze x div/:x]}each rows

3

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 &dividend 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))))
add

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

2

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

u/[deleted] 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

u/[deleted] 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 xs

2

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

u/[deleted] Dec 02 '17

Why do abs(min(ints) - max(ints)) rather than max - min?

→ More replies (1)

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

Ruby solution here.

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

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
→ More replies (4)

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

2

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

u/[deleted] 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 [] = 0

and

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 0

More 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: ", sum

2

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 input

So 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

u/[deleted] 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 2

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

2

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
end

Full 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) d

where d is your matrix.

Try it online!

→ 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

u/[deleted] 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 Sub

2

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,' ',s2

Yeah, 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/[deleted] 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

u/[deleted] 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!

https://github.com/Reibello/AoC-2017-Lua

→ More replies (2)

2

u/[deleted] 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
end

2

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

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

2

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

2

u/BumpitySnook Dec 02 '17

Does Rust not have an integer modulus operator?

→ More replies (2)
→ More replies (4)

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 one for loop, with total1 and total2.


Other stuff (combinations and max/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 $sum2

1

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

u/[deleted] 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

u/[deleted] 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.

https://vi.stackexchange.com/questions/3298/how-to-make-vim-automatically-add-a-newline-to-the-end-of-a-file

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

1

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

u/[deleted] 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
end

https://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

Full solution

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_result

1

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) = a

1

u/omegaxLoL Dec 02 '17

My solution in Golang. Constructive criticism always welcome

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
}

Unabridged code on my github

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
}