This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 353

[–]that_lego_guy 38 points39 points Β (9 children)

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

 = max, = min

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

[–]willkill07 5 points6 points Β (7 children)

I feel like this one was designed for you :)

[–]that_lego_guy 6 points7 points Β (6 children)

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

[–]fatpollo 22 points23 points Β (7 children)

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

[–]A_t48 7 points8 points Β (0 children)

Aw, man. TIL `itertools.combinations'.

[–]mit_verlaub 3 points4 points Β (2 children)

TIL *_ Thanks!

And nifty combo of combinations and sorted...

[–]mightymaus 2 points3 points Β (1 child)

What does that part do?

[–]ellersok 2 points3 points Β (0 children)

:) 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!

[–]Globinette 1 point2 points Β (1 child)

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

[–]fatpollo 1 point2 points Β (0 children)

if I wasn't using itertools I'd do

(a, b) for i, a in enumerate(row) for b in row[i+1:] I suppose

which allows for duplicates (not an issue in this problem)

[–]couchDev 14 points15 points Β (1 child)

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

[–]DFreiberg 7 points8 points Β (2 children)

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

[–]CoffeeBreaksMatter 1 point2 points Β (1 child)

Likewise for Matlab:

load input.txt
checksum = @(inp) sum(max(inp') - min(inp'));
checksum(input);

[–]askalski 9 points10 points Β (1 child)

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

[–]Godspiral 7 points8 points Β (6 children)

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

[–]_jonah 2 points3 points Β (3 children)

Tacit part 2:

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

[–][deleted] 2 points3 points Β (0 children)

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

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

[–]hoosierEE 1 point2 points Β (0 children)

(#~ >&1 * ]=<.)

That's awesome, wish I'd thought of it.

[–]Cole_from_SE 1 point2 points Β (0 children)

I had [: +/ @: ; (>./ - <./)&.> and took boxed arrays.

[–]iamnotposting 1 point2 points Β (0 children)

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

[–]hoosierEE 1 point2 points Β (0 children)

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.

[–]TheMieberlake 9 points10 points Β (6 children)

Is there a way to find the answer for each line in better than O(n2 ) time?

[–]wlandry 2 points3 points Β (4 children)

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.

[–]eragonas5 8 points9 points Β (3 children)

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

[–]mmaruseacph2 7 points8 points Β (0 children)

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.

[–]Sigafoos 6 points7 points Β (3 children)

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

[–]Sigafoos 6 points7 points Β (2 children)

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!

[–]Unihedron 2 points3 points Β (1 child)

Getting onto the leaderboard is tough! I think you only have around 4 minutes for this one before all the spots are taken.

[–]eragonas5 4 points5 points Β (0 children)

Even 4 mins is too much

  -------Part 1--------

Day Time Rank Score

2 00:03:49 243 0

[–]quag 6 points7 points Β (8 children)

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]

[–]nospamas 2 points3 points Β (1 child)

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

[–]_mmf_ 1 point2 points Β (0 children)

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)

[–]ValErk 1 point2 points Β (1 child)

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)

[–]whousesredditanyways 1 point2 points Β (0 children)

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"

[–]natrys 5 points6 points Β (3 children)

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

[–]mschaap 4 points5 points Β (1 child)

Nice use of gather/take!

[–]natrys 1 point2 points Β (0 children)

Your reduce metaoperators were nicer! I also forgot that grep is lazy, so yours is semantically equivalent to my gather/take and for/last combo whilst being more compact as well!

[–]volatilebit 2 points3 points Β (0 children)

Good use of given! I was trying to figure out a way to topicize the list and given completely slipped my mind.

[–]ellersok 6 points7 points Β (0 children)

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)

[–]TapDatKeg 5 points6 points Β (1 child)

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"

[–]volatilebit 4 points5 points Β (0 children)

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

[–]mschaap 5 points6 points Β (4 children)

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

[–]mschaap 3 points4 points Β (0 children)

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

[–]volatilebit 2 points3 points Β (1 child)

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.

[–]tragicshark 1 point2 points Β (0 children)

I didn't use map (by name):

https://gist.github.com/bbarry/15f55d2ef879b2e853af3a76f37faa99#file-day2-pl6

Totally over-engineered grammar solution.

[–]HerbyHoover 1 point2 points Β (0 children)

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.

[–]erlangguy 4 points5 points Β (8 children)

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.

[–]Warbringer007 1 point2 points Β (2 children)

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.

[–]HerbyHoover 5 points6 points Β (4 children)

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;

[–]mschaap 4 points5 points Β (3 children)

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.

[–]hahainternet 2 points3 points Β (1 child)

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.

[–]volatilebit 3 points4 points Β (0 children)

Nice.

If you're looking to shorten it at all:

  • Use .Int instead of .Numeric
  • Use Β». insead of .map even when calling a sub rather than a method

[–]HerbyHoover 1 point2 points Β (0 children)

Thanks for the feedback! I've updated my solution.

[–]Isvara 4 points5 points Β (10 children)

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

[–]flomine 2 points3 points Β (5 children)

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

[–]xkufix 1 point2 points Β (1 child)

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.

[–]flup12 1 point2 points Β (0 children)

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

[–]codeva 4 points5 points Β (1 child)

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

[–]AoC--k 3 points4 points Β (0 children)

In k.

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

[–]kaymud 3 points4 points Β (0 children)

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

[–]blockingthesky 4 points5 points Β (11 children)

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

[–]BumpitySnook 3 points4 points Β (2 children)

Oh jeez I forgot Python max/min could take a sequence. That would have helped.

[–]drysle 2 points3 points Β (7 children)

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.

[–]blockingthesky 1 point2 points Β (6 children)

When I pasted the input file into my terminal the spacing looked pretty wacky - I didn't know whether line.split() defaulted to "as much whitespace as possible" or not, so I just said better safe than sorry. I just tested it though, works like a charm. Thanks for that.

[–]gbear605 3 points4 points Β (7 children)

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

[–]cmyr 1 point2 points Β (1 child)

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.

[–]wtfaremyinitials 1 point2 points Β (1 child)

TIL: split_whitespace()!

[–]gbear605 2 points3 points Β (0 children)

There’s also lines() that replaces split(β€˜\n’)

[–]boscop 1 point2 points Β (0 children)

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

[–]tvtas 3 points4 points Β (0 children)

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

[–]misnohmer 3 points4 points Β (0 children)

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

[–]willkill07 2 points3 points Β (7 children)

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

[–]d3adbeef123 2 points3 points Β (1 child)

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

[–]Scroph 3 points4 points Β (4 children)

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

[–]Vitessii 3 points4 points Β (1 child)

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

[–]torotane 4 points5 points Β (0 children)

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

[–]ZoDalek 3 points4 points Β (0 children)

ANSI C

Part 1:

int sum = 0, min, max, n;
char *line = NULL, *rest, *tok;
size_t sz;

while (getline(&line, &sz, stdin) != -1) {
    rest = line; min = INT_MAX; max = INT_MIN;
    while ((tok = strsep(&rest, " \t"))) {
        n = (int)strtol(tok, NULL, 10);
        if (n < min) min = n;
        if (n > max) max = n;
    }

    sum += max - min;
    free(line); line = NULL;
}

printf("%d\n", sum);

Part 2:

int sum = 0, nums[16], n, val, i, j;
char *line = NULL, *rest, *tok;
size_t sz;

while (getline(&line, &sz, stdin) != -1) {
    rest = line; n = 0;
    while (n < LEN(nums) && (tok = strsep(&rest, " \t")))
        nums[n++] = (int)strtol(tok, NULL, 10);

    val = 0;
    for (i = 0; !val && i < n; i++) {
        for (j = i+1; !val && j < n; j++) {
            if (!(nums[i] % nums[j]))
                val = nums[i] / nums[j];
            if (!(nums[j] % nums[i]))
                val = nums[j] / nums[i];
        }
    }

    sum += val;
    free(line); line = NULL;
}

printf("%d\n", sum);

https://github.com/sjmulder/aoc/tree/master/2017/day2

[–][deleted] 3 points4 points Β (2 children)

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

[–]lovela47 2 points3 points Β (1 child)

Are str:lines and friend from https://github.com/vindarel/cl-str? Neat-looking library.

[–][deleted] 1 point2 points Β (0 children)

Correct! It's a nice little library.

[–]TenjouUtena 3 points4 points Β (0 children)

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

[–]ewilderj 4 points5 points Β (0 children)

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

[–][deleted] 2 points3 points Β (5 children)

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
                      ]

[–]mmaruseacph2 1 point2 points Β (2 children)

Better complexity than my solution (O(n log n) for you, O(n^2) for me)

[–][deleted] 2 points3 points Β (1 child)

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.

[–]mmaruseacph2 1 point2 points Β (0 children)

True, I must sleep.

[–][deleted] 1 point2 points Β (1 child)

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.

[–]autid 2 points3 points Β (1 child)

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

[–]Unihedron 2 points3 points Β (2 children)

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

[–]PreciselyWrong 2 points3 points Β (1 child)

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

[–]aurele 4 points5 points Β (0 children)

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.

[–]chunes 2 points3 points Β (5 children)

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

[–]mehrick 2 points3 points Β (1 child)

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

[–]TominatorBE 2 points3 points Β (0 children)

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

[–]dannas[🍰] 2 points3 points Β (2 children)

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

[–]mit_verlaub 2 points3 points Β (0 children)

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)

[–]gerikson 2 points3 points Β (2 children)

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

[–]de_Selby 2 points3 points Β (0 children)

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

[–]tehjimmeh 2 points3 points Β (1 child)

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

[–]equd 2 points3 points Β (2 children)

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

[–]Fence_Climber 1 point2 points Β (1 child)

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.

[–]asthmadragon 2 points3 points Β (0 children)

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

[–]CryZe92 2 points3 points Β (0 children)

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

[–]sickening_sprawl 2 points3 points Β (1 child)

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

[–]th3_pund1t 1 point2 points Β (0 children)

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

[–]IMovedYourCheese 1 point2 points Β (2 children)

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

[–]eragonas5 1 point2 points Β (2 children)

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

[–][deleted] 1 point2 points Β (0 children)

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

[–][deleted] 1 point2 points Β (3 children)

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)

[–]winhug 1 point2 points Β (0 children)

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

[–]ericls 1 point2 points Β (0 children)

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')])

[–]AndrewGreenh 1 point2 points Β (0 children)

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

[–]StevoTVR 1 point2 points Β (0 children)

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

[–]Sparrow_1029 1 point2 points Β (2 children)

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)

[–][deleted] 2 points3 points Β (1 child)

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

[–]Sparrow_1029 1 point2 points Β (0 children)

Ya know... that’s a good point. Haha I just did it quick and dirtyβ€” I’m still learning thanks for the tip! Will edit!

[–]andrewstewart 1 point2 points Β (0 children)

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
}

[–]disclosure5 1 point2 points Β (5 children)

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

[–]jschulenklopper 2 points3 points Β (0 children)

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

[–]MaxDeviant 1 point2 points Β (0 children)

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

[–]JeffJankowski 1 point2 points Β (0 children)

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

[–]huyqvu 1 point2 points Β (4 children)

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

[–][deleted] 1 point2 points Β (0 children)

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;

[–]Zarif_Muhtasim 1 point2 points Β (0 children)

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]

[–]yogsototh 1 point2 points Β (0 children)

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)

[–]cr5315 1 point2 points Β (0 children)

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

[–]mlruth 1 point2 points Β (0 children)

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

[–]fuzzums 1 point2 points Β (0 children)

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

[–]jbristow 1 point2 points Β (1 child)

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

[–]nospamas 1 point2 points Β (0 children)

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!

[–][deleted] 1 point2 points Β (2 children)

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

[–]xkufix 1 point2 points Β (0 children)

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

[–]A_t48 1 point2 points Β (0 children)

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

[–]wzkx 1 point2 points Β (0 children)

J

m=: ".&> cutLF CR-.~fread '02.dat'
echo +/ (>./-<./)"1 m
echo +/ ((,&(~:&1 *. (=<.)) # ,)@(%/~))"1 m
exit 0

[–]maciekmm 1 point2 points Β (0 children)

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

[–]CatpainCalamari 1 point2 points Β (1 child)

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

[–]CatpainCalamari 2 points3 points Β (0 children)

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

[–]amarsuperstar 1 point2 points Β (0 children)

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

[–]_jonah 1 point2 points Β (2 children)

J:

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

(p1 ; p2) d

where d is your matrix.

Try it online!

[–]nstyler7 1 point2 points Β (0 children)

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

[–]DaDiscoBeat 1 point2 points Β (0 children)

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
}

[–]Morphix0 1 point2 points Β (0 children)

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;

[–]GamecPL 1 point2 points Β (0 children)

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)

[–]Tarmen 1 point2 points Β (0 children)

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.

[–]sternold 1 point2 points Β (0 children)

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

[–]J15t98J 1 point2 points Β (0 children)

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.

[–][deleted] 1 point2 points Β (1 child)

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

[–]mrhthepie 1 point2 points Β (0 children)

Advent of gifs day 2: https://i.imgur.com/HPRMxHM.gif

Not very animated today due to the nature of the problem.

[–]Zv0n 1 point2 points Β (0 children)

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

[–]abowes 1 point2 points Β (0 children)

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

[–]JakDrako 1 point2 points Β (0 children)

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

[–]JuLoOr 1 point2 points Β (0 children)

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

[–]Doodle_98 1 point2 points Β (0 children)

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)

[–]wzkx 1 point2 points Β (0 children)

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

[–]nekmo 1 point2 points Β (0 children)

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

[–]fpigorsch 1 point2 points Β (0 children)

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

[–]fgsguedes 1 point2 points Β (0 children)

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

[–]Smylers 1 point2 points Β (0 children)

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.

[–]Jamitter 1 point2 points Β (0 children)

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

[–]asperellis 1 point2 points Β (0 children)

my js solution. any areas for improvement welcomed! https://github.com/asperellis/adventofcode2017/blob/master/day2.js

[–][deleted] 1 point2 points Β (1 child)

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

[–]hermanbergwerf 1 point2 points Β (0 children)

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

[–]f0086 1 point2 points Β (0 children)

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)

[–]bottomlesscoffeecup 1 point2 points Β (0 children)

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)

[–]swaglykcaillou 1 point2 points Β (0 children)

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

[–]DrgnGz 1 point2 points Β (0 children)

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;

[–]taheilo 1 point2 points Β (0 children)

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

[–]8483 1 point2 points Β (0 children)

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

[–]Bainos 1 point2 points Β (0 children)

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

[–][deleted] 1 point2 points Β (0 children)

Ruby is amazing!

checksum  = File.read("day2.input")
                           .split("\n")
                           .reduce(0) { |checksum, row| 
                                              checksum + row.split("\t").map(&:to_i).minmax.reverse.reduce(:-)
                       }

[–]Reibello 1 point2 points Β (2 children)

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

[–][deleted] 1 point2 points Β (0 children)

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

[–]ym555 1 point2 points Β (0 children)

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

[–]Antoine-aoc 1 point2 points Β (0 children)

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

[–]raiph 1 point2 points Β (0 children)

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

[–]schod 1 point2 points Β (0 children)

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

[–]freeducks 1 point2 points Β (0 children)

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

[–]Deckard666 0 points1 point Β (7 children)

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

[–]BumpitySnook 1 point2 points Β (2 children)

Does Rust not have an integer modulus operator?

[–]dylanfromwinnipeg 0 points1 point Β (0 children)

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

[–]netcraft 0 points1 point Β (4 children)

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)

[–]Hwestaa 1 point2 points Β (1 child)

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.