DEV Community

loading...
Cover image for Advent of Code 2020 Solution Megathread - Day 6: Custom Customs

Advent of Code 2020 Solution Megathread - Day 6: Custom Customs

rpalo profile image Ryan Palo Updated on ・1 min read

Yesterday, a lot of you finished quickly and were looking for more to keep you occupied on a Saturday. All of the golfed one-liners were really funny to read through.

The Puzzle

In today’s puzzle, we're helping our fellow passengers fill out customs forms. 26 questions represented by 'a'-'z', and the presence of a particular letter in our input means a "yes" for that question for that particular person. We're just helping tally up the results.

The Leaderboards

As always, this is the spot where I’ll plug any leaderboard codes shared from the community.

Ryan's Leaderboard: 224198-25048a19
Enter fullscreen mode Exit fullscreen mode

If you want to generate your own leaderboard and signal boost it a little bit, send it to me either in a DEV message or in a comment on one of these posts and I'll add it to the list above.

Yesterday’s Languages

Updated 03:07PM 12/12/2020 PST.

Language Count
Ruby 3
Go 2
Python 2
Haskell 2
JavaScript 2
C 2
Rust 2
COBOL 1
Elixir 1
D 1
TypeScript 1

Merry Coding!

Discussion (28)

pic
Editor guide
Collapse
bgaster profile image
Benedict Gaster

OK, today seemed pretty straightforward, although it took me to reach task 2 to have the insight that it was union and then intersect... oh well it is a Sunday :-)

Anyway Haskell was a nice fit and simply used set operations on lists to keep with my somewhat weak goal of using lists.

main  = do xs <- IOT.readFile "day6_input" <&> fmap (map unpack . T.lines) . T.splitOn "\n\n"
           print (sum $ fmap (length . foldr1 union) xs)
           print (sum $ fmap (length . foldr1 intersect) xs)
Enter fullscreen mode Exit fullscreen mode
Collapse
kais_blog profile image
Kai • Edited

I've created a step-by-step tutorial (TypeScript) again:

and I did something with bits, just for fun:

Collapse
mgasparel profile image
Mike Gasparelli

Clever solution. I had an instinct that I could use binary to solve Day5, although couldn't quite flesh out a working solution (ended up solving it in a different way). It didn't even dawn on me that you could use binary for this challenge, although it seems obvious now. 👍

Collapse
meseta profile image
Yuan Gao • Edited

Python one-liners, thanks to set theory and list comprehension, and map
Part 1:

sum([len(set(entry.replace("\n",""))) for entry in open("input.txt").read().split("\n\n")])
Enter fullscreen mode Exit fullscreen mode

Part 2:

sum(len(set.intersection(*map(set, entry.split()))) for entry in open("input.txt").read().split("\n\n"))
Enter fullscreen mode Exit fullscreen mode

I try to explain this more fully at dev.to/meseta/advent-of-code-2020-...

Collapse
willsmart profile image
willsmart

Python impl today. Prob not great python but works.

print(reduce(
    lambda acc, v: acc + len(
        set(v.replace('\n', ''))
    ),
    open("6.txt").read().split('\n\n'),
    0
))

print(reduce(
    lambda acc, v: acc + len(reduce(
        lambda acc, v: acc & v,
        map(
            lambda v: set(v), 
            v.split('\n')
        )
    )),
    open("6.txt").read().split('\n\n'),
    0
))
Enter fullscreen mode Exit fullscreen mode

Tomorrow will try something like prolog?!
Failing that, maybe Haskell.

Collapse
readyready15728 profile image
readyready15728

Ruby, part 2:

require 'set'

groups = File.read('06.txt').split /\n\n/

puts (groups.map do |group|
  responses = group.split(/\n/).map { |response| Set.new(response.each_char) }
  responses.inject { |product, current| product.intersection(current) }.length
end).sum
Enter fullscreen mode Exit fullscreen mode
Collapse
benwtrent profile image
Benjamin Trent

Rust!

use std::collections::HashSet;

#[aoc_generator(day6)]
fn to_vec(input: &str) -> Vec<Vec<Vec<char>>> {
    input
        .split("\n\n")
        .map(|i| {
            i.lines()
                .map(|s| s.chars().collect::<Vec<char>>())
                .collect()
        })
        .collect()
}

#[aoc(day6, part1)]
fn answer_count(input: &Vec<Vec<Vec<char>>>) -> usize {
    input
        .iter()
        .map(|group| {
            group
                .iter()
                .flat_map(|v| v.iter().map(|c| *c).collect::<HashSet<char>>())
                .collect::<HashSet<char>>()
                .len()
        })
        .sum()
}

#[aoc(day6, part2)]
fn abs_answer_count(input: &Vec<Vec<Vec<char>>>) -> usize {
    input
        .iter()
        .map(|group| {
            group
                .iter()
                .map(|v| v.iter().map(|c| *c).collect::<HashSet<char>>())
                .fold(Option::None, |l, g| {
                    if l.is_none() {
                        Some(g.clone())
                    } else {
                        Some(
                            l.unwrap_or(HashSet::new())
                                .intersection(&g)
                                .map(|c| *c)
                                .collect(),
                        )
                    }
                })
                .unwrap_or(HashSet::new())
                .len()
        })
        .sum()
}
Enter fullscreen mode Exit fullscreen mode
Collapse
ballpointcarrot profile image
Christopher Kruse

Ugh, made it too late for this day (but I had it done in time for the problem, honest!).

Used HashSet to my benefit here, as I could apply set theory to the problem and get it done easily.

As always, in Github.

use aoc_runner_derive::{aoc, aoc_generator};
use std::collections::HashSet;

#[aoc_generator(day6)]
fn parse_input_day6(input: &str) -> Vec<String> {
    input
        .split("\n\n")
        .map(|group| String::from(group))
        .collect()
}

#[aoc(day6, part1)]
fn sum_group_questions(input: &Vec<String>) -> usize {
    let answers: Vec<HashSet<char>> = input
        .iter()
        .map(|group| group.chars().filter(|x| *x != '\n').collect())
        .collect();
    answers.iter().map(|group| group.len()).sum()
}

#[aoc(day6, part2)]
fn sum_group_common_questions(input: &Vec<String>) -> usize {
    input
        .iter()
        .map(|group| {
            let mut first_run = true;
            group
                .lines()
                .map(|answers| answers.chars().collect::<HashSet<char>>())
                .fold(HashSet::new(), |memo, ans| {
                    if memo.is_empty() && first_run {
                        first_run = false;
                        ans.clone()
                    } else {
                        let intersect = memo.intersection(&ans).cloned().collect();
                        intersect
                    }
                })
                .len()
        })
        .sum()
}
Enter fullscreen mode Exit fullscreen mode
Collapse
galoisgirl profile image
Anna

COBOL

   IDENTIFICATION DIVISION.
   PROGRAM-ID. AOC-2020-06-2.
   AUTHOR. ANNA KOSIERADZKA.

   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
       SELECT INPUTFILE ASSIGN TO "d6.input"
       ORGANIZATION IS LINE SEQUENTIAL.

   DATA DIVISION.
   FILE SECTION.
     FD INPUTFILE
     RECORD IS VARYING IN SIZE FROM 1 to 99
     DEPENDING ON REC-LEN.
     01 INPUTRECORD PIC X(99).
   WORKING-STORAGE SECTION.
     01 FILE-STATUS PIC 9 VALUE 0.
     01 REC-LEN PIC 9(2) COMP.
     01 WS-GROUP-ANSWERS PIC 9 OCCURS 26 TIMES.
     01 WS-CHAR PIC X.

   LOCAL-STORAGE SECTION.
     01 I UNSIGNED-INT VALUE 1.
     01 C UNSIGNED-INT VALUE 1.
     01 X UNSIGNED-INT VALUE 1.
     01 GROUP-SIZE UNSIGNED-INT VALUE 0.
     01 GROUP-TOTAL UNSIGNED-INT VALUE 0.
     01 TOTAL UNSIGNED-INT VALUE 0.

   PROCEDURE DIVISION.
   001-MAIN.
       PERFORM 004-INIT-VARIABLES.
       OPEN INPUT INPUTFILE.
       PERFORM 002-READ UNTIL FILE-STATUS = 1.
       CLOSE INPUTFILE.
       PERFORM 004-NEXT-GROUP.
       DISPLAY TOTAL.
       STOP RUN.

   002-READ.
        READ INPUTFILE
            AT END MOVE 1 TO FILE-STATUS
            NOT AT END PERFORM 003-PROCESS-RECORD
        END-READ.

   003-PROCESS-RECORD.
       IF REC-LEN = 0 THEN
          PERFORM 004-NEXT-GROUP
       ELSE 
          PERFORM 005-PROCESS-ROW
       END-IF.

   004-INIT-VARIABLES.
       PERFORM VARYING I FROM 1 BY 1 UNTIL I > 26
          MOVE 0 TO WS-GROUP-ANSWERS(I)
       END-PERFORM.
       MOVE 0 TO GROUP-SIZE.
       MOVE 0 TO GROUP-TOTAL.

   004-NEXT-GROUP.
       IF GROUP-SIZE > 0 THEN
          PERFORM 006-TALLY-GROUP-TOTAL
       END-IF.
       ADD GROUP-TOTAL TO TOTAL.
       PERFORM 004-INIT-VARIABLES.

   005-PROCESS-ROW.
       ADD 1 TO GROUP-SIZE.
       PERFORM VARYING I FROM 1 BY 1 UNTIL I > REC-LEN
          MOVE INPUTRECORD(I:1) TO WS-CHAR
          COMPUTE C = FUNCTION ORD(WS-CHAR)
          COMPUTE X = WS-GROUP-ANSWERS(C - 97) + 1
          MOVE X TO WS-GROUP-ANSWERS(C - 97)
       END-PERFORM.

   006-TALLY-GROUP-TOTAL.
       PERFORM VARYING I FROM 1 BY 1 UNTIL I > 26
          IF WS-GROUP-ANSWERS(I) = GROUP-SIZE THEN 
             ADD 1 TO GROUP-TOTAL
          END-IF 
       END-PERFORM.
Enter fullscreen mode Exit fullscreen mode
Collapse
particleflux profile image
Stefan Linke

2 Solutions again.

Go:

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "os"
)

func countQuestions(group []byte) (int, int) {
    counts := map[byte]int{}
    numPeople := 1
    for _, question := range group {
        if question == '\n' {
            numPeople++
        } else {
            counts[question]++
        }
    }

    numAllYes := 0
    for _, c := range counts {
        if c == numPeople {
            numAllYes++
        }
    }

    return len(counts), numAllYes
}

func main() {
    input, _ := ioutil.ReadAll(os.Stdin)
    groups := bytes.Split(input, []byte("\n\n"))

    sum1, sum2 := 0, 0
    for _, group := range groups {
        a, b := countQuestions(group)
        sum1 += a
        sum2 += b
    }

    fmt.Println(sum1, sum2)
}
Enter fullscreen mode Exit fullscreen mode

And tweet-sized PHP:

<?for($i=0,$z=explode("

",file_get_contents('input'));$z[$i];){$a+=count($f=count_chars($z[$i++],1))-(($n=$f[10])>0);foreach($f as$k=>$v)$b+=$k!=10&$v==$n+1;}echo"$a $b";
Enter fullscreen mode Exit fullscreen mode
Collapse
flwidmer profile image
flwidmer

I decided to do this year in Haskell. Perhaps if it gets too crazy, I'll revert to what I know better, but until now it's been fun.

I might start a library with the groups and addAll functions, seems I'm going to use them for every puzzle...

import Data.List.Split ( splitOn )
import Data.List ( intersect, nub )

main :: IO ()
main = do
    input <- readFile "input"
    putStrLn "day6"
    print $ solve1 input
    print $ solve2 input

solve1 :: String -> Int
solve1 a = 
  let grouped = groups a
      answers = map (filter (\x -> x `elem` ['a'..'z']) . nub) grouped
  in  addAll answers

solve2 :: String -> Int
solve2 a =
  let grouped = map lines $ groups a
      intersected = map (foldr1 intersect) grouped 
  in  addAll intersected

addAll :: [[a]] -> Int 
addAll = sum . map length 

groups :: String -> [String]
groups = splitOn "\n\n"
Enter fullscreen mode Exit fullscreen mode
Collapse
mgasparel profile image
Mike Gasparelli

I thought the most obvious way to do this would be to intersect a bunch of HashSets, but seemed to be more short & sweet to just check that every character in the first line was contained in every other line 🤷

Part 1

    public class Part1 : Puzzle<IEnumerable<PlaneGroup>, int>
    {
        public override int SampleAnswer => 11;

        public override IEnumerable<PlaneGroup> ParseInput(string rawInput)
            => rawInput
                .Split(Environment.NewLine + Environment.NewLine)
                .Where(line => line.Length > 0)
                .Select(group =>
                    new PlaneGroup(
                        group
                            .Split(Environment.NewLine)
                            .Where(x => x.Length > 0)));

        public override int Solve(IEnumerable<PlaneGroup> input)
            => input.Sum(x => x.CountDistinctAnswers());
    }
Enter fullscreen mode Exit fullscreen mode

Part 2

    public class Part2 : Part1
    {
        public override int SampleAnswer => 6;

        public override int Solve(IEnumerable<PlaneGroup> input)
            => input.Sum(x => x.CountIntersectingAnswers());
    }
Enter fullscreen mode Exit fullscreen mode

PlaneGroup

    public class PlaneGroup
    {
        List<string> answers;

        public PlaneGroup(IEnumerable<string> answers)
        {
            this.answers = answers.ToList();
        }

        public int CountDistinctAnswers()
            => new HashSet<char>(answers.SelectMany(a => a))
                .Count();

        public int CountIntersectingAnswers()
            => answers.First()
                .Count(c => answers.All(a => a.Contains(c)));
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
mellen profile image
Matt Ellen

I spent a long time trying to get a regex to work for part 2, but I have given up for the time being. Got a short couple of answers for this:

function testScoresp1()
{
  const input = document.getElementsByTagName('pre')[0].innerHTML;
  const groups = input.split('\n\n');
  return groups.map(group => new Set(group.replaceAll('\n', ''))).reduce((sum, group) => sum + group.size, 0);
}

function testScoresp2()
{
  const input = document.getElementsByTagName('pre')[0].innerHTML;
  const groups = input.split('\n\n');
  const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
  return alphabet.reduce((sum, letter) =>
  {
    return sum + groups.filter(group => group.trim().split('\n').every(line => line.indexOf(letter) > -1)).length;
  }, 0);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
sleeplessbyte profile image
Derk-Jan Karrenbeld

Only took a few minutes today; here is what I got in Ruby:

require 'benchmark'

class GroupAnswers
  def self.from_lines(lines)
    GroupAnswers.new(lines.map(&:chomp))
  end

  def initialize(people)
    questions = people.join('').chars.uniq
    self.count = questions.count { |q| people.all? { |l| l.include?(q) } }
  end

  def to_i
    self.count
  end

  private

  attr_accessor :count
end

groups = File
  .read('input.txt')
  .split(/\n\n/)

Benchmark.bmbm do |b|
  b.report do
    puts groups.sum { |group| GroupAnswers.from_lines(group.split(/\n/)).to_i }
  end
end
Enter fullscreen mode Exit fullscreen mode
Collapse
harrygibson profile image
Harry Gibson

Python. A bit less elegant than some of the other python versions already posted but the same idea using set theory

n = 0
checkset = set()
with open('input.txt', 'r') as in_file:
    for l in in_file:
        if l.strip() == '':
            n += len(checkset)
            checkset.clear()
        else:
            checkset.update((c for c in l.strip()))
    if l.strip() != '': n += len(checkset)
print(f"Part 1: total is {n}")

checkset = set()
new_group = True
n = 0
with open('input.txt', 'r') as in_file:
    for l in in_file:
        if l.strip() == '':
            n += len(checkset)
            checkset.clear()
            new_group = True
        else:
            if new_group:
                checkset.update((c for c in l.strip()))
                new_group = False
            else:
                # must be in every person: equivalent to set intersection 
                checkset.intersection_update((c for c in l.strip()))
    if l.strip() != '': n += len(checkset)
print(f"Part 2: total is {n}")
Enter fullscreen mode Exit fullscreen mode
Collapse
vncz profile image
Vincenzo Chianese
(ns day6 (:require [clojure.string :refer [split]]
                   [clojure.set :refer [intersection]]))

(def input (-> "./day6input.txt"
               (clojure.core/slurp)
               (split #"\n\n")))

(def any-answers (->> input
                      (map #(re-seq #"\w" %))
                      (map set)
                      (reduce #(+ %1 (count %2)) 0))) ; Part 1

(def all-answers (->> input
                      (map #(split % #"\n"))
                      (map #(map (fn [x] (set (clojure.core/char-array x))) %))
                      (map #(apply intersection %))
                      (reduce #(+ %1 (count %2)) 0))) ; Part 2
Enter fullscreen mode Exit fullscreen mode
Collapse
kudostoy0u profile image
Kudos Beluga • Edited

Javascript answer, Part 1 and 2 in one script, change the part2 boolean to false if you want a part 1 answer.
Looking at other people's responses, mine feels very inefficient :(

let fs = require("fs"), part2 = false, n = 0;
fs.readFile("input.txt","utf8",(err,data) => {
if (err) throw err;
let veryuppercount = 0;
data.split(/\n\s/gi).map(e => {
  if (part2) {
  let uppercount = 0;
 e = e.split(/\n/g);
 e[0].split("").map(f => {
   let counter = 0;
   e.slice(1,e.length).map(g => {
   g.split("").map(h => {
     if (h == f) counter++
   })})
   if (counter == e.length-1) uppercount++
 })
  veryuppercount += uppercount;
  } else {
  e = e.replace(/\n/g,"")
  if (e) {
 let noduplicate = [...new Set(e.split(""))];
 n += noduplicate.length
  }}})
if (part2) console.log(veryuppercount)
else console.log(n)
})
Enter fullscreen mode Exit fullscreen mode
Collapse
galoisgirl profile image
Anna

JavaScript - I did it in COBOL first, but still wanted to practice reduce a bit.

const readline = require('readline');
const fs = require('fs');

const A_INDEX = "a".charCodeAt(0);

let lines = [];

function getClearAnswers() {
  return Array(26).fill(0)
}

const readInterface = readline.createInterface({
    input: fs.createReadStream('./example.txt'),
});

readInterface.on('line', function(line) {
  lines.push(line)
});

readInterface.on('close', function() {
  const result = lines.reduce((res, line) => {
    if (line.length == 0) {
      if (res.groupSize == 0) {
        return res
      }
      return {
        total: res.total + Object.values(res.groupAnswers).reduce((acc, x) => acc + (x == res.groupSize ? 1 : 0), 0),
        groupSize: 0,
        groupAnswers: getClearAnswers()
      }
    }
    const indices = line.split('').map(l => l.charCodeAt(0) - A_INDEX)
    return {
      total: res.total,
      groupSize: res.groupSize + 1,
      groupAnswers: indices.reduce((acc, x) => acc.fill(acc[x] + 1, x, x + 1), res.groupAnswers)
    }
  }, {
    total: 0,
    groupSize: 0,
    groupAnswers: getClearAnswers()
  });

  console.log(result.total)
})
Enter fullscreen mode Exit fullscreen mode
Collapse
patryk profile image
Patryk Woziński

Yesterday I had no time to post my solution in Elixir, but there is!

defmodule AdventOfCode.Day6 do
  def part1(file_path) do
    file_path
    |> read_all_answers()
    |> Enum.map(&how_many_answers(&1, :step1))
    |> Enum.sum()
  end

  def part2(file_path) do
    file_path
    |> read_all_answers()
    |> Enum.map(&how_many_answers(&1, :step2))
    |> Enum.sum()
  end

  defp read_all_answers(file_path) do
    file_path
    |> File.read!()
    |> String.split("\n\n", trim: true)
    |> Enum.map(&String.split/1)
  end

  defp how_many_answers(list, :step1), do: how_many_answers(list, &MapSet.union/2)
  defp how_many_answers(list, :step2), do: how_many_answers(list, &MapSet.intersection/2)

  defp how_many_answers(list, f) do
    list
    |> Enum.map(&String.to_charlist/1)
    |> Enum.map(&MapSet.new/1)
    |> Enum.reduce(f)
    |> Enum.count()
  end
end
Enter fullscreen mode Exit fullscreen mode
Collapse
erikbackman profile image
Erik Bäckman • Edited

Haskell:

module Main where

import Control.Arrow (Arrow((&&&)))
import Data.List.Split (splitOn)
import Control.Monad (join)
import Data.List (nub, intersect)

parseInput :: String -> [[String]]
parseInput = fmap lines . splitOn "\n\n"

solveP1 :: [[String]] -> Int
solveP1 = sum . fmap (length . nub . join)

solveP2 :: [[String]] -> Int
solveP2 = sum . fmap answers
  where
    answers [x]    = length x
    answers (x:xs) = length . foldr intersect x $ xs

main :: IO ()
main = print . (solveP1 &&& solveP2) . parseInput =<< readFile "./day6inp.txt"
Enter fullscreen mode Exit fullscreen mode
Collapse
vncz profile image
Vincenzo Chianese • Edited

I've solved this using Clojure for the sake of. It seems to be the shortest one so far.

(ns day6 (:require [clojure.string :refer [split]]
                   [clojure.set :refer [intersection]]))

(def input (-> "./day6input.txt"
               (clojure.core/slurp)
               (split #"\n\n")))

(def any-answers (->> input
                      (map #(re-seq #"\w" %))
                      (map set)
                      (reduce #(+ %1 (count %2)) 0))) ; Part 1

(def all-answers (->> input
                      (map #(split % #"\n"))
                      (map #(map (fn [x] (set (clojure.core/char-array x))) %))
                      (map #(apply intersection %))
                      (reduce #(+ %1 (count %2)) 0))) ; Part 2
Enter fullscreen mode Exit fullscreen mode
Collapse
rpalo profile image
Ryan Palo Author

A little late to the party, but I got it done before bed time 😁

Day6.h:

#ifndef AOC2020_DAY6_H
#define AOC2020_DAY6_H

/// Day 6: Custom Customs
/// 
/// Search through lists of questionnaire answers.
/// Each questionnaire is 26 questions, so a yes to question 'b' would
/// be represented by the presence of 'b' in the output line.
/// People are one to a line, and parties are separated by a blank line.

#include <stdlib.h>
#include <stdio.h>

/// Return the number of letters that are present for any line in a group
int tally_anyone_yeses(FILE* fp);

/// Return the number of letters that are present in every line in a group
int tally_everyone_yeses(FILE* fp);

/// Run both 
int day6(void);
#endif
Enter fullscreen mode Exit fullscreen mode

Day6.c:

#include "Day6.h"

#include <stdio.h>
#include <string.h>

/// Number of letters in the alphabet
#define LETTERS 26

/// Max number of chars per line (yes to all plus newline plus NULL)
#define MAX_LINE_SIZE (LETTERS + 2)

int tally_anyone_yeses(FILE* fp) {
  int counts[LETTERS] = {0};
  char line[MAX_LINE_SIZE] = {0};

  // Log each occurrence of a character.
  while (!feof(fp)) {
    fgets(line, MAX_LINE_SIZE, fp);
    if (line[0] == '\n') break;

    for (int i = 0; line[i] != '\n' && line[i]; i++) {
      int index = line[i] - 'a';
      counts[index]++;
    }
    memset(line, 0, MAX_LINE_SIZE);
  }

  // Loop through and find the total count of those that appeared.
  int total = 0;
  for (int i = 0; i < LETTERS; i++) {
    if (counts[i] > 0) total++;
  }
  return total;
}

/// Run the part 1 code on the input file.
static int part1() {
  FILE* fp;
  fp = fopen("data/day6.txt", "r");
  if (fp == NULL) {
      printf("Couldn't open input file.\n");
      exit(EXIT_FAILURE);
  }

  // Loop through and add up the total for each group.
  int total = 0;
  while (!feof(fp)) {
      total += tally_anyone_yeses(fp);
  }

  fclose(fp);
  return total;
}

int tally_everyone_yeses(FILE* fp) {
  int counts[LETTERS] = {0};
  char line[MAX_LINE_SIZE] = {0};
  int people_count = 0;

  // Loop through the group and add up everybody's answers.
  while (!feof(fp)) {
    fgets(line, MAX_LINE_SIZE, fp);
    if (line[0] == '\n') break;

    people_count++;
    for (int i = 0; line[i] != '\n' && line[i]; i++) {
      int index = line[i] - 'a';
      counts[index]++;
    }
    memset(line, 0, MAX_LINE_SIZE);
  }

  // Count the number of letters where everyone answered it yes
  // i.e. number of yeses == number of people
  int total = 0;
  for (int i = 0; i < LETTERS; i++) {
    if (counts[i] == people_count) total++;
  }
  return total;
}

/// Run the part 2 code on the input file.
int part2() {
  FILE* fp;
  fp = fopen("data/day6.txt", "r");
  if (fp == NULL) {
      printf("Couldn't open input file.\n");
      exit(EXIT_FAILURE);
  }

  // Loop through and add up the total for each group.
  int total = 0;
  while (!feof(fp)) {
      total += tally_everyone_yeses(fp);
  }

  fclose(fp);
  return total;
}

int day6() {
  printf("====== Day 6 ======\n");
  printf("Part 1: %d\n", part1());
  printf("Part 2: %d\n", part2());
  return EXIT_SUCCESS;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
katafrakt profile image
Paweł Świątkowski

Re yesterday: actually my solution was in D, but I don't see it listed in the table.

Collapse
rpalo profile image
Ryan Palo Author

OK cool, I wasn't 100% sure. I'll update that.

Collapse
katafrakt profile image
Paweł Świątkowski

Yeah, I should've mentioned that in the original. Those C-like languages look pretty much all the same if you don't know some particular details.

Thread Thread
rpalo profile image
Ryan Palo Author

Haha! Yeah, I was thinking, "I'm pretty sure that's not Go, but maybe it's C#? Or C++?" I just thought of inspecting the HTML classes yesterday after running into a similar issue. 😂

Collapse
readyready15728 profile image
readyready15728 • Edited

Ruby, part 1:

require 'set'

groups = File.read('06.txt').split /\n\n/

puts (groups.map do |group|
  Set.new(group.split(/\n/).join.each_char).length
end).sum
Enter fullscreen mode Exit fullscreen mode
Collapse
thibpat profile image
Thibaut Patel

Here is my walkthrough for day 6 in JavaScript:

Source code: github.com/tpatel/advent-of-code-2...