Day 6

Previous: Day 05 | Next: Day 07

Papers, please

AUTO-ACQUIRED DATA FOLLOWS...

archivist/day06.c
archivist/day06.c
#include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    const int coffset = 97;
    
    int countbits(int N){
        int count = 0;
        while(N > 0){
            count += N & 1;
            N >>= 1;
        }
        return count;
    }
    
    int part1(char* in);
    int part2(char* in);
    
    int main (int argc, char**argv){
        int  length = 0;
        FILE *f = fopen(argv[1], "r");
        char *input;
        if (!f) return -1; 
        fseek(f, 0, SEEK_END);
        length = ftell(f);
        rewind(f);
        input = (char*)malloc(sizeof(char) * (length+1));
        fread(input, sizeof(char), length, f);
        fclose(f);
        ((char*)input)[length] = '\0';
    
        //part1(input);    
        part2(input);
        return 0;
    }
    
    int part1(char* in){
        char * line = 0;
        int sum = 0;
        int groupbits = 0;
        while((line = strsep(&in, "\n"))!= NULL){
            if(strlen(line) == 0){
                sum += countbits(groupbits);
                groupbits = 0;
                continue;
            }
            for(int i=0;i<strlen(line);i++){
                groupbits |= (1 << ((int)line[i] - coffset));
            }
        }
        printf("Sum of sums: %d\n", sum);
    }
    
    int part2(char* in){
        char * line = 0;
        int sum = 0;
        int groupbits = ~0;
        int passengerbits = 0;
        while((line = strsep(&in, "\n"))!= NULL){
            if(strlen(line) == 0){
                sum += countbits(groupbits);
                groupbits = ~0;
                continue;
            }
            for(int i=0;i<strlen(line);i++){
                passengerbits |= (1 << ((int)line[i] - coffset));
            }
            groupbits &= passengerbits;
            passengerbits = 0;
        }
        printf("Sum of sums: %d\n", sum);
    }
    
day-6/assembly-day06.S
day-6/assembly-day06.S
extern printf
    extern getchar
    extern exit
    
    section .text
    global _start
    
    ;;; undef for part 1
    %define part2
        
    %macro printd 1                    ; Print a number
        mov rdi, fmt_str
        mov rsi, %1
        call printf
    %endmacro
    
    _start:
        mov rdi, hello
        call printf
    .start:
        call getchar                ; Read a char
        cmp eax, -1
        jz .end                        ; If rax = (int32)-1, end of input
    
        cmp al, 10                    ; If al = \n
        je .nl
        
        mov byte [lastc], al         ; Set The last char to al
    
        sub rax, 97                    ; rax -= 'a'
        inc byte [decl + rax]        ; Increment declarations for this char
    
        jmp .start                     ; Loop again
    
    .nl:                            ; Newline found
        cmp byte [lastc], 10        ; If its a single newline just ignore it
        je .group                    ; If second newline, this is the end of a group
        mov byte [lastc], al
        inc byte [in_group]            ; Another person in the group
        jmp .start
    .group:
        mov rcx, 26
        xor rdx, rdx
        mov al, byte [in_group]
    .loop:
    %ifndef part2    
        cmp byte [decl + rcx-1], 0    ; Is this declaration >0
        setne dl                    ; Set dl if declaration not zero
    %else
        cmp byte [decl + rcx-1], al ; Did everyone in the group answer yes?
        sete dl
    %endif
        add dword [sum], edx        ; Increment sum if declaration not zero
        mov byte [decl + rcx-1], 0    ; Clear declarations 
        loop .loop                     ; Loop until counter = 0
        
        mov dword [in_group], 0        ; Clear # people in group
        jmp .start                    ; Loop again
    .end:
        printd [sum]                ; Print the sum
        xor rdi, rdi                ; Exit 0
        call exit
    
    section .data
        hello db "Advent of Code day 6", 10, 0
        fmt_str db "%d", 10, 0
        sum dd 0                     ; Sum of declarations
        in_group db 0                 ; Number of people in current group
        lastc db 0                    ; Last char
    section .bss
        decl resb 26                ; Declarations (one per letter)
    
day-6/day06.lisp
day-6/day06.lisp
(defun load-records (filename)
        (with-open-file (stream filename)
            (loop for line = (read-line stream nil)
                while line
                collect (mapcar (lambda (s) (coerce s 'list))
                    (cons line
                        (loop for subline = (read-line stream nil)
                            while (and subline (not (string= subline "")))
                            collect subline))))))
    
    (defun solve (reduce-function records)
        (apply '+
            (mapcar #'length
                (mapcar (lambda (r) (reduce reduce-function r)) records))))
    
    (let ((records (load-records #p"input06.txt")))
        (format t "~a~%" (solve #'union records))
        (format t "~a~%" (solve #'intersection records)))
    
day-6/julia-day06.jl
day-6/julia-day06.jl
using BenchmarkTools
    function main()::Tuple{Int64, Int64}
        open("day6input") do file
            answers = split(read(file, String), r"\n\n|\r\n\r\n"; keepempty=false)
            silver = 0
            gold = 0
            for group in answers
                questions = unique([response for person in split(group) for response in person])
                responses = split(group)
                for question in questions
                    all(person->question in person, responses) && (gold += 1)
                end
                silver += length(questions)
            end
            @show (silver, gold)
        end
    end
    
    @time main()
    @time better()
    
day-6/ruby-day06.rb
day-6/ruby-day06.rb
#!/usr/bin/env ruby -w
    # frozen_string_literal: true
    
    groups = File
      .read("input/06.txt")
      .split("\n\n")
      .map { _1.split.map &:chars }
    
    silver = groups.sum { _1.reduce(:|).size }
    gold = groups.sum { _1.reduce(:&).size }
    
    puts(
      "Day 05\n" \
      "==================\n" \
      "✮: #{silver}\n" \
      "★: #{gold}"
    )
    
    # golf 90 characters
    # $/="\n\n";p$<.map{_1.split.map &:chars}.then{|l|[:|,:&].map{|f|l.sum{ _1.reduce(f).size}}}
    
deutschanon/deutschanon-day06.c
deutschanon/deutschanon-day06.c
#include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc,char** argv){
        FILE *input;
        if(argc < 2){
            input = fopen("input.txt","r");
        }else{
            input = fopen(argv[1],"r");
        }
        int gruppe = 0;
        int summe = 0;
        int sum = 0;
        int antworten[26];
        int alle[26];
        int zahler = 0;
        char newline = 0;
        char c = 0;
        for(int i = 0; i < 26;i++){
            antworten[i] = 0;
            alle[i] = 0;
        }
        while((c = getc(input)) != EOF){
            if(c != '\n'){
                antworten[c - 97] = 1;
                alle[c - 97] = alle[c - 97] + 1;
                if(newline == 1){
                    newline = 0;
                }
            }else{
                if(newline == 0){
                    newline = 1;
                    zahler++;
                }else{
                    for(int i = 0; i < 26; i++){
                        gruppe = gruppe + antworten[i];
                        antworten[i] = 0;
                        if(alle[i] == zahler){
                            sum = sum + 1;
                        }
                        alle[i] = 0;
                    }
                    summe = summe + gruppe;
                    zahler = 0;
                    gruppe = 0;
                    newline = 0;
                }
            }
        }
        for(int i = 0; i < 26; i++){
            gruppe = gruppe + antworten[i];
            antworten[i] = 0;
            if(alle[i] == (zahler)){
                sum = sum + 1;
            }
            alle[i] = 0;
        }
        summe = summe + gruppe;
        printf("P1: %d\nP2: %d\n",summe,sum);
        return 0;
    }
    
javanon/day06.js
javanon/day06.js
dataset = document.querySelector("body > pre");
    questionList = dataset.innerText.split("\n\n");
    
    // fix up shitty newline at the end of the file.
    questionList[questionList.length - 1] = questionList[questionList.length - 1].substring(0, questionList[questionList.length - 1].length - 1);
    
    function a (questionList) {
        return questionList.reduce( (acc, question) => acc += new Set(question.replace(/\s/g, '')).size, 0);
    }
    
    function b (questionList) {
        return questionList.reduce( (acc, question) => acc + question.split('\n').map(q => new Set(q)).reduce((a, b) => new Set([...a].filter(c => [...b].includes(c)))).size, 0);
    }
    
steveklabnik/steveklabnik-day06.rs
steveklabnik/steveklabnik-day06.rs
fn solve(input: &str) -> (u32, u32) {
        input
            .split("\n\n")
            .map(|s| {
                s.lines()
                    .map(|s| s.bytes().fold(0_u32, |acc, b| acc | (1 << (b - b'a'))))
                    .fold((0, !0), |(a, b), i| (a | i, b & i))
            })
            .fold((0, 0), |(aa, ab), (a, b)| {
                (aa + a.count_ones(), ab + b.count_ones())
            })
    }
    
unknown-cnile/ucnile-day06.c
unknown-cnile/ucnile-day06.c
#include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <unistd.h>
    
    void die(char *str) {
        fprintf(stderr, "[ERROR] %s\n", str);
        exit(-1);
    }
    
    FILE *map_file(const char *filename) {
        int fd;
        if ((fd = open(filename, O_RDONLY)) == -1) die("failed to open file");
        struct stat fd_stat;
        if (fstat(fd, &fd_stat) == -1) die("failed to stat file");
        void *data;
        // never unmapped, probably fine
        if ((data = mmap(NULL,
                         fd_stat.st_size,
                         PROT_READ,
                         MAP_PRIVATE,
                         fd, 0)) == MAP_FAILED) die("failed to map file");
        close(fd);
        return fmemopen(data, fd_stat.st_size, "r");
    }
    
    int main(int argc, char **argv) {
        // read input
        FILE *fd = map_file("test.txt");
        char data[64];
        int any_acc = 0;
        int all_acc = 0;
        unsigned int cur_any = 0;
        unsigned int cur_all = ~0;
        while (fgets(data, 64, fd) != NULL) {
            if (data[0] < 'a') {
                any_acc += __builtin_popcount(cur_any);
                all_acc += __builtin_popcount(cur_all);
                cur_any = 0;
                cur_all = ~0;
            } else {
                unsigned int row = 0;
                for (int i = 0; data[i] >= 'a'; i++) {
                    row |= 1 << (data[i] - 'a');
                }
                cur_any |= row;
                cur_all &= row;
            }
        }
        any_acc += __builtin_popcount(cur_any);
        all_acc += __builtin_popcount(cur_all);
        printf("P1: %d\n", any_acc);
        printf("P2: %d\n", all_acc);
        return 0;
    }
    

Tags: