2022 day 2 (bash)
This commit is contained in:
111
2022/day02/Makefile
Normal file
111
2022/day02/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@#$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@#$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
89
2022/day02/README.org
Normal file
89
2022/day02/README.org
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
** --- Day 2: Rock Paper Scissors ---
|
||||||
|
The Elves begin to set up camp on the beach. To decide whose tent gets
|
||||||
|
to be closest to the snack storage, a giant
|
||||||
|
[[https://en.wikipedia.org/wiki/Rock_paper_scissors][Rock Paper
|
||||||
|
Scissors]] tournament is already in progress.
|
||||||
|
|
||||||
|
Rock Paper Scissors is a game between two players. Each game contains
|
||||||
|
many rounds; in each round, the players each simultaneously choose one
|
||||||
|
of Rock, Paper, or Scissors using a hand shape. Then, a winner for that
|
||||||
|
round is selected: Rock defeats Scissors, Scissors defeats Paper, and
|
||||||
|
Paper defeats Rock. If both players choose the same shape, the round
|
||||||
|
instead ends in a draw.
|
||||||
|
|
||||||
|
Appreciative of your help yesterday, one Elf gives you an /encrypted
|
||||||
|
strategy guide/ (your puzzle input) that they say will be sure to help
|
||||||
|
you win. "The first column is what your opponent is going to play: =A=
|
||||||
|
for Rock, =B= for Paper, and =C= for Scissors. The second column--"
|
||||||
|
Suddenly, the Elf is called away to help with someone's tent.
|
||||||
|
|
||||||
|
The second column, you reason, must be what you should play in response:
|
||||||
|
=X= for Rock, =Y= for Paper, and =Z= for Scissors. Winning every time
|
||||||
|
would be suspicious, so the responses must have been carefully chosen.
|
||||||
|
|
||||||
|
The winner of the whole tournament is the player with the highest score.
|
||||||
|
Your /total score/ is the sum of your scores for each round. The score
|
||||||
|
for a single round is the score for the /shape you selected/ (1 for
|
||||||
|
Rock, 2 for Paper, and 3 for Scissors) plus the score for the /outcome
|
||||||
|
of the round/ (0 if you lost, 3 if the round was a draw, and 6 if you
|
||||||
|
won).
|
||||||
|
|
||||||
|
Since you can't be sure if the Elf is trying to help you or trick you,
|
||||||
|
you should calculate the score you would get if you were to follow the
|
||||||
|
strategy guide.
|
||||||
|
|
||||||
|
For example, suppose you were given the following strategy guide:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
A Y
|
||||||
|
B X
|
||||||
|
C Z
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
This strategy guide predicts and recommends the following:
|
||||||
|
|
||||||
|
- In the first round, your opponent will choose Rock (=A=), and you
|
||||||
|
should choose Paper (=Y=). This ends in a win for you with a score of
|
||||||
|
/8/ (2 because you chose Paper + 6 because you won).
|
||||||
|
- In the second round, your opponent will choose Paper (=B=), and you
|
||||||
|
should choose Rock (=X=). This ends in a loss for you with a score of
|
||||||
|
/1/ (1 + 0).
|
||||||
|
- The third round is a draw with both players choosing Scissors, giving
|
||||||
|
you a score of 3 + 3 = /6/.
|
||||||
|
|
||||||
|
In this example, if you were to follow the strategy guide, you would get
|
||||||
|
a total score of =15= (8 + 1 + 6).
|
||||||
|
|
||||||
|
/What would your total score be if everything goes exactly according to
|
||||||
|
your strategy guide?/
|
||||||
|
|
||||||
|
Your puzzle answer was =11841=.
|
||||||
|
|
||||||
|
** --- Part Two ---
|
||||||
|
The Elf finishes helping with the tent and sneaks back over to you.
|
||||||
|
"Anyway, the second column says how the round needs to end: =X= means
|
||||||
|
you need to lose, =Y= means you need to end the round in a draw, and =Z=
|
||||||
|
means you need to win. Good luck!"
|
||||||
|
|
||||||
|
The total score is still calculated in the same way, but now you need to
|
||||||
|
figure out what shape to choose so the round ends as indicated. The
|
||||||
|
example above now goes like this:
|
||||||
|
|
||||||
|
- In the first round, your opponent will choose Rock (=A=), and you need
|
||||||
|
the round to end in a draw (=Y=), so you also choose Rock. This gives
|
||||||
|
you a score of 1 + 3 = /4/.
|
||||||
|
- In the second round, your opponent will choose Paper (=B=), and you
|
||||||
|
choose Rock so you lose (=X=) with a score of 1 + 0 = /1/.
|
||||||
|
- In the third round, you will defeat your opponent's Scissors with Rock
|
||||||
|
for a score of 1 + 6 = /7/.
|
||||||
|
|
||||||
|
Now that you're correctly decrypting the ultra top secret strategy
|
||||||
|
guide, you would get a total score of =12=.
|
||||||
|
|
||||||
|
Following the Elf's instructions for the second column, /what would your
|
||||||
|
total score be if everything goes exactly according to your strategy
|
||||||
|
guide?/
|
||||||
|
|
||||||
|
Your puzzle answer was =13022=.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
42
2022/day02/aoc.bash
Executable file
42
2022/day02/aoc.bash
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# aoc.bash: Advent of Code 2022, day 1
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
. common.bash
|
||||||
|
|
||||||
|
declare -A outcome=( # shape is known
|
||||||
|
[A X]=$((3+1)) [A Y]=$((6+2)) [A Z]=$((0+3))
|
||||||
|
[B X]=$((0+1)) [B Y]=$((3+2)) [B Z]=$((6+3))
|
||||||
|
[C X]=$((6+1)) [C Y]=$((0+2)) [C Z]=$((3+3))
|
||||||
|
)
|
||||||
|
declare -A outcome2=( # result is known
|
||||||
|
[A X]=$((0+3)) [A Y]=$((3+1)) [A Z]=$((6+2))
|
||||||
|
[B X]=$((0+1)) [B Y]=$((3+2)) [B Z]=$((6+3))
|
||||||
|
[C X]=$((0+2)) [C Y]=$((3+3)) [C Z]=$((6+1))
|
||||||
|
)
|
||||||
|
declare -a tot
|
||||||
|
|
||||||
|
parse() {
|
||||||
|
local input
|
||||||
|
|
||||||
|
while read -r input; do
|
||||||
|
(( tot[1] += outcome[$input] ))
|
||||||
|
(( tot[2] += outcome2[$input] ))
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
solve() {
|
||||||
|
res="${tot[$1]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
exit 0
|
17
2022/day02/aoc.h
Normal file
17
2022/day02/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
|
||||||
|
#endif /* _AOC_H_ */
|
67
2022/day02/common.bash
Executable file
67
2022/day02/common.bash
Executable file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
49
2022/day02/common.c
Normal file
49
2022/day02/common.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
3
2022/day02/input/example.txt
Normal file
3
2022/day02/input/example.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
A Y
|
||||||
|
B X
|
||||||
|
C Z
|
2500
2022/day02/input/input.txt
Normal file
2500
2022/day02/input/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user