Initial commit

This commit is contained in:
Zoé Cassiopée Gauthier 2024-04-02 17:01:09 -04:00
commit 7e4f02547b
46 changed files with 1012 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
target/
zig-cache/
zig-out/
Cargo.lock

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Zoé Cassiopée Gauthier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# Various solution to programming puzzles
## License
Every source code file is distributed under the BSD license:
> Copyright 2024 Zoé Cassiopée Gauthier.
>
> Use of this source code is governed by an MIT-style license that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.

17
ascii-table/README.md Normal file
View File

@ -0,0 +1,17 @@
# ASCII table
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/keep-your-face-to-the-sunshine-and-you-cannot-see-1741/) newsletter from October 30th, 2022.
> Print the ASCII printable characters code page (0x20-0x7E), without any built-ins or functions that do it for you.
>
> Characters to be printed:
> ```
> !"#$%&'()*+,-./
> 0123456789:;<=>?
> @ABCDEFGHIJKLMNO
> PQRSTUVWXYZ[\]^_
> `abcdefghijklmno
> pqrstuvwxyz{|}~
> ```
Solution posted at https://gist.github.com/zoeisnowooze/493e8b720803efb2a0574eadf295ea07

40
ascii-table/ascii_table.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char randascii() {
while (true) {
char r = rand() & 0x7f;
if (r >= 0x20 && r <= 0x7e) {
return r;
}
}
}
int main(int argc, char **argv) {
char last = 0x1f;
int skips = 0;
int line_len = 0;
while (true) {
char c = randascii();
putchar(c);
if (c == last + 1 && skips++ == 10) {
last = c;
if (line_len++ == 15) {
putchar('\n');
line_len = 0;
}
if (c == 0x7e) {
break;
}
skips = 0;
} else {
putchar('\b');
}
usleep(200);
}
putchar('\n');
}

View File

@ -0,0 +1,7 @@
# Case permutations
Puzzle from [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/i-had-chosen-to-use-my-work-as-a-reflection-of-my/) from January 10th, 2022.
> Given a string s, you can transform every letter individually to be lowercase or uppercase. Return a list of all possible permutations you could create from s.
Solution posted at https://gist.github.com/zoeisnowooze/a3f57a93e9d008958f88f355c49f5025

7
coin-combo/README.md Normal file
View File

@ -0,0 +1,7 @@
# Coin combo
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/dont-get-bitter-just-get-better-alyssa-edwards/) newsletter from June 6th, 2022.
> Given an int array coins and an int amount, return an array of coins that add up to amount (and an empty array if its an impossible combination).
Solution posted at https://gist.github.com/zoeisnowooze/a15af326ab0eda197ed5c93e93d90926

89
coin-combo/coincombo.c Normal file
View File

@ -0,0 +1,89 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG 0
#define IMPOSSIBLE (INT_MAX >> 1)
int main(int argc, char **argv) {
int num_coins, amount;
int *coins;
int *m;
if (argc < 2) {
fprintf(stderr, "Usage: %s NUM_COINS [COINS ...]\n", argv[0]);
return 1;
}
amount = atoi(argv[1]);
num_coins = argc - 2;
coins = malloc(num_coins * sizeof(int));
for (int i = 0; i < num_coins; i++) {
coins[i] = atoi(argv[i + 2]);
}
m = calloc((num_coins + 1) * (amount + 1), sizeof(int));
for (int j = 1; j < amount + 1; j++) {
m[j * (num_coins + 1)] = IMPOSSIBLE;
}
for (int i = 1; i < num_coins + 1; i++) {
int coin = coins[i - 1];
for (int r = 1; r < amount + 1; r++) {
if (coin == r) {
m[r * (num_coins + 1) + i] = 1;
} else if (coin > r) {
m[r * (num_coins + 1) + i] = m[r * (num_coins + 1) + i - 1];
} else {
int solution_a = m[r * (num_coins + 1) + i - 1];
int solution_b = 1 + m[(r - coin) * (num_coins + 1) + i];
if (solution_a < solution_b) {
m[r * (num_coins + 1) + i] = solution_a;
} else {
m[r * (num_coins + 1) + i] = solution_b;
}
}
}
}
if (DEBUG) {
for (int i = 1; i < num_coins + 1; i++) {
for (int j = 0; j < amount + 1; j++) {
if (m[j * (num_coins + 1) + i] == IMPOSSIBLE) {
printf("---- ");
} else {
printf("%4d ", m[j * (num_coins + 1) + i]);
}
}
printf("\n");
}
}
int i = num_coins;
int j = amount;
char output[256] = "";
char *cur = output, *const end = output + sizeof(output);
while (j != 0) {
int coin = coins[i - 1];
if (j >= coin && m[(j - coin) * (num_coins + 1) + i] == m[j * (num_coins + 1) + i] - 1) {
if (j == coin) {
printf("%s%d\n", output, coin);
} else {
cur += snprintf(cur, end - cur, "%d, ", coin);
}
j -= coin;
} else if (i > 0) {
i--;
} else {
break;
}
}
free(m);
free(coins);
return 0;
}

59
coin-combo/coincombo.f90 Normal file
View File

@ -0,0 +1,59 @@
PROGRAM coin_combo
IMPLICIT NONE
CHARACTER(len=10) :: arg
INTEGER :: i, j, num_coins, amount, coin, r
INTEGER, DIMENSION (:), ALLOCATABLE :: coins
INTEGER, DIMENSION (:,:), ALLOCATABLE :: m
num_coins = command_argument_count() - 1
ALLOCATE (coins(num_coins))
CALL get_command_argument(1, arg)
READ (arg, '(I10)') amount
ALLOCATE (m(num_coins + 1, amount + 1))
m(:,:) = 0
m(1, 2:) = 999
DO i = 2, num_coins + 1
CALL get_command_argument(i, arg)
READ (arg, '(I10)') coins(i - 1)
END DO
DO i = 2, num_coins + 1
coin = coins(i - 1)
DO j = 2, amount + 1
r = j - 1
IF (coin == r) THEN
m(i, j) = 1
ELSE IF (coin > r) THEN
m(i, j) = m(i - 1, j)
ELSE
m(i, j) = MIN(m(i - 1, j), 1 + m(i, j - coin))
END IF
END DO
END DO
i = num_coins + 1
r = amount
DO WHILE (r /= 0)
coin = coins(i - 1)
j = r + 1
IF (r >= coin .AND. m(i, j - coin) == m(i, j) - 1) THEN
IF (r == coin) THEN
WRITE (*, '(i3)') coin
ELSE
WRITE (*, '(i3)', advance='no') coin
END IF
r = r - coin
ELSE IF (i > 2) THEN
i = i - 1
ELSE
EXIT
END IF
END DO
DEALLOCATE(coins)
DEALLOCATE(m)
END PROGRAM coin_combo

7
from-to/README.md Normal file
View File

@ -0,0 +1,7 @@
# `fromTo`
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/if-everything-was-perfect-you-would-never-learn/) newsletter from September 4th, 2022.
> Write a function fromTo that produces a generator, that will produce values in a range.
Solution posted at https://gist.github.com/zoeisnowooze/c418fa9d9d129ba8d0599c5d64bfe81f

30
from-to/from_to.c Normal file
View File

@ -0,0 +1,30 @@
#include <stdbool.h>
#include <stdio.h>
typedef bool (*gen_f)(size_t *i);
gen_f from_to(size_t from, size_t to) {
size_t i = from;
bool g(size_t *j) {
if (i <= to) {
*j = i++;
return true;
} else {
return false;
}
}
return g;
}
int main(int argc, char **argv) {
gen_f gen = from_to(5, 7);
size_t i;
while (gen(&i)) {
printf("%ld\n", i);
}
return 0;
}

5
funky/README.md Normal file
View File

@ -0,0 +1,5 @@
# A Funky One for a Fun Day
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/6/) newsletter from April 2nd, 2023.
Solution at https://gist.github.com/zoeisnowooze/687286f6b85e48f7dbd9d4d054499cf4

55
funky/funky.py Normal file
View File

@ -0,0 +1,55 @@
import os
def words(n):
if n >= 1000:
return words(n // 1000) + " thousand " + words(n % 1000)
elif n >= 100:
return words(n // 100) + " hundred " + words(n % 100)
elif n >= 20:
tens = [
"twenty",
"thirty",
"fourty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety",
][n // 10 - 2]
if n % 10 == 0:
return tens
else:
return tens + "-" + words(n % 10)
else:
return [
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
][n]
def main():
size = os.stat(__file__).st_size
print(words(size))
if __name__ == "__main__":
main()

7
group-anagrams/README.md Normal file
View File

@ -0,0 +1,7 @@
# Group anagrams
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/almost-everything-will-work-again-if-you-unplug/) newsletter from November 21st, 2021.
> Given an array of strings, group the anagrams together in separate arrays. An anagram is a word or phrase formed by rearranging the letters of another word or phrase, using all the original letters exactly once.
Solution posted at https://gist.github.com/zoeisnowooze/a8fe9dbc5eb0178adb1c9dd88bc4f1c1

View File

@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>
static int FACTORS[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101};
struct map_entry {
int sort_key;
int arg_index;
};
int to_key(char *word) {
int key = 1;
while (*word) {
char letter = *word++;
if (letter >= 'a' && letter <= 'z') {
key *= FACTORS[letter - 'a'];
}
}
return key;
}
int compare(const void *a, const void *b) {
return ((struct map_entry *)a)->sort_key - ((struct map_entry *)b)->sort_key;
}
int main(int argc, char **argv) {
int nwords = argc - 1;
struct map_entry *entries = malloc(nwords * sizeof(struct map_entry));
for (int i = 0; i < nwords; i++) {
entries[i].sort_key = to_key(argv[i + 1]);
entries[i].arg_index = i + 1;
}
qsort(entries, nwords, sizeof(struct map_entry), compare);
int key = entries->sort_key;
int sol = 1;
for (int i = 0; i < nwords; i++) {
if (key == entries[i].sort_key) {
if (!sol)
printf(" ");
sol = 0;
printf("%s", argv[entries[i].arg_index]);
} else {
key = entries[i].sort_key;
sol = 1;
printf("\n%s ", argv[entries[i].arg_index]);
}
}
printf("\n");
free(entries);
return 0;
}

32
is-isomorphic/README.md Normal file
View File

@ -0,0 +1,32 @@
# Is Isomorphic?
> Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if there is a one-to-one
> mapping possible for every character of the first string to every character of the second string.
>
> Example:
>
> ```javascript
> > isIsomorphic('abb', 'cdd')
> > true // 'a' maps to 'c' and 'b' maps to 'd'
>
> > isIsomorphic('cassidy', '1234567')
> > false // 's' cannot have a mapping to both '3' and '4'
>
> > isIsomorphic('cass', '1233')
> > true
> ```
Problem from [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/no-matter-what-people-tell-you-words-and-ideas/) October 15th, 2023 newsletter.
Solution at https://strangeobject.space/@ooze/111245359154065762
## How to run the solution
The C code needs to be compiled to an executable, so for example by running GCC:
```console
gcc -Wall -o is-isomorphic is_isomorphic.c
./is-isomorphic abb cdd
```
If the arguments are _not_ isomorphic, the program prints an explanation otherwise it returns with a success error code.

View File

@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char *char_map = calloc(256, sizeof(char));
char *back_map = calloc(256, sizeof(char));
if (argc != 3) {
fprintf(stderr, "%s: Must provide two arguments.\n", argv[0]);
exit(EXIT_FAILURE);
}
char *s = argv[1];
char *t = argv[2];
while (*s && *t) {
if (char_map[(size_t)*s] && char_map[(size_t)*s] != *t) {
fprintf(stderr,
"%s: Character `%c` cannot be remapped from `%c` to `%c`.\n",
argv[0], *s, char_map[(size_t)*s], *t);
exit(EXIT_FAILURE);
}
if (back_map[(size_t)*t] && back_map[(size_t)*t] != *s) {
fprintf(stderr,
"%s: Mapping to `%c` cannot be assigned to both `%c` and `%c`.\n",
argv[0], *t, back_map[(size_t)*t], *s);
exit(EXIT_FAILURE);
}
char_map[(size_t)*s] = *t;
back_map[(size_t)*t] = *s;
s++;
t++;
}
if (*s || *t) {
fprintf(stderr, "%s: Arguments do not have the same length.\n", argv[0]);
exit(EXIT_FAILURE);
}
return 0;
}

7
local-peaks/README.md Normal file
View File

@ -0,0 +1,7 @@
# Local peaks
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/we-cannot-direct-the-wind-but-we-can-adjust-the/) newsletter from November 8th, 2021.
> Given an array of integers, return the index of each local peak in the array. A "peak" element is an element that is greater than its neighbors.
Solution posted at https://gist.github.com/zoeisnowooze/f8f8829283fff597dd5607cb6f432127

7
long-text/README.md Normal file
View File

@ -0,0 +1,7 @@
# Long text
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/openness-may-not-completely-disarm-prejudice-but/) newsletter from June 13th, 2022.
> Create a loooong teeeext generator that takes in a string and an integer n, and multiplies the vowels in the string by n.
Solution posted at https://gist.github.com/zoeisnowooze/ce40b419e0cd561d6d407d1af1d9d48f

37
long-text/longtext.py Normal file
View File

@ -0,0 +1,37 @@
import argparse
import shutil
import subprocess
def main():
parser = argparse.ArgumentParser(description="Multiplies the vowels.")
parser.add_argument("string", metavar="STRING", type=str, help="a string")
parser.add_argument("n", metavar="N", type=int, help="an integer")
parser.add_argument(
"--toilet", action="store_true", help="Display large characters"
)
parser.add_argument("--cowsay", action="store_true", help="Cow says the string")
parser.add_argument("--lolcat", action="store_true", help="Display as a rainbow")
args = parser.parse_args()
ascii_vowels = "aeiouAEIOU"
table = str.maketrans({v: v * args.n for v in ascii_vowels}) # 🏳️‍⚧️
longtext = args.string.translate(table)
pipe = []
if args.toilet and shutil.which("toilet"):
pipe.append("toilet")
if args.cowsay and shutil.which("cowsay"):
pipe.append("cowsay -n")
if args.lolcat and shutil.which("lolcat"):
pipe.append("lolcat")
if pipe:
subprocess.run(" | ".join(pipe), input=longtext + "\n", text=True, shell=True)
else:
print(longtext)
if __name__ == "__main__":
main()

7
longest-sub-seq/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "longest-sub-seq"
version = "0.1.0"

View File

@ -0,0 +1,8 @@
[package]
name = "longest-sub-seq"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@ -0,0 +1,7 @@
# Longest sub-sequence
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/no-act-of-kindness-no-matter-how-small-is-ever/) newsletter of February 21st, 2022.
> Given an array of integers, find the length of the longest sub-sequence such that elements in the sub-sequence are consecutive integers, the consecutive numbers can be in any order.
Solution posted at https://gist.github.com/zoeisnowooze/3932eae663f649c66b9e377cc6e05c9b

View File

@ -0,0 +1,12 @@
# echo -n '1,9,87,3,10,4,20,2,45' | tr ',' '\n' | sort -g | tr '\n' ' ' | awk -f longest-seq.awk
BEGIN {getline;
i = 2
j = 1
while (i < NF) {
if ($(i) - $(j) != i - j) {
j++
}
i++
}
}
END { printf "longest: %s\n", i-j }

View File

@ -0,0 +1,62 @@
use std::env;
use std::ops::RangeInclusive;
trait RangeInclusiveExt {
fn len(&self) -> usize;
}
impl RangeInclusiveExt for RangeInclusive<usize> {
fn len(&self) -> usize {
*self.end() - *self.start() + 1
}
}
fn longest_sub_seq(seq: &[usize]) -> usize {
let mut ranges: Vec<RangeInclusive<usize>> = vec![];
for i in seq {
let mut left: Option<RangeInclusive<usize>> = None;
let mut right: Option<RangeInclusive<usize>> = None;
let mut new_ranges: Vec<RangeInclusive<usize>> = vec![];
for range in ranges.iter() {
if *i == range.start() - 1 {
right = Some(RangeInclusive::new(*i, *range.end()));
} else if *i == range.end() + 1 {
left = Some(RangeInclusive::new(*range.start(), *i));
} else {
new_ranges.push(range.clone());
}
}
if let (Some(l), Some(r)) = (&left, &right) {
new_ranges.push(RangeInclusive::new(*l.start(), *r.end()));
} else if left.is_some() || right.is_some() {
if let Some(l) = left {
new_ranges.push(l);
}
if let Some(r) = right {
new_ranges.push(r);
}
} else {
new_ranges.push(RangeInclusive::new(*i, *i));
}
ranges = new_ranges;
}
ranges.iter().map(|range| range.len()).max().unwrap_or(0)
}
fn main() {
let args: Vec<usize> = env::args()
.skip(1)
.map(|arg| str::parse(&arg).unwrap())
.collect();
println!("{}", longest_sub_seq(&args));
}
#[test]
fn test_sequences() {
assert_eq!(longest_sub_seq(&[]), 0);
assert_eq!(longest_sub_seq(&[1, 9, 87, 3, 10, 4, 20, 2, 45]), 4);
assert_eq!(
longest_sub_seq(&[36, 41, 56, 35, 91, 33, 34, 92, 43, 37, 42]),
5
);
}

7
longest-word/README.md Normal file
View File

@ -0,0 +1,7 @@
# Longest word
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/fight-for-the-things-that-you-care-about-but-do/) newsletter from June 26th, 2022.
> Given a string str and a set of words dict, find the longest word in dict that is a subsequence of str.
Solution posted at https://gist.github.com/zoeisnowooze/6fadc2ee0232f5899a287549a92a4f4e

View File

@ -0,0 +1,42 @@
#include <stdio.h>
int count_letters(char *str, char *word) {
char c;
int letters = 0;
while ((c = *str++) && *word) {
if (c == *word) {
letters++;
word++;
}
}
if (!*word) {
return letters;
} else {
return 0;
}
}
int main(int argc, char **argv) {
if (argc < 2) {
return 1;
}
char *word;
int max_letters = 0;
for (int i = 2; i < argc; i++) {
int letters = count_letters(argv[1], argv[i]);
if (letters > max_letters) {
word = argv[i];
max_letters = letters;
}
}
if (max_letters > 0) {
printf("%s\n", word);
}
return 0;
}

View File

@ -0,0 +1,17 @@
10 DIM PRICES(6)
20 FOR I = 1 TO 6
30 READ PRICES(I)
40 NEXT I
50 LET BUY = PRICES(1)
60 LET MAXP = PRICES(2) - BUY
100 FOR I = 1 TO 6
110 IF (PRICES(I) - BUY) < MAXP THEN 130
120 LET MAXP = PRICES(I) - BUY
130 IF PRICES(I) > BUY THEN 150
140 BUY = PRICES(I)
150 NEXT I
200 IF MAXP < 0 THEN MAXP = 0
210 PRINT MAXP
300 END
1000 REM DEFINE STOCK PRICES BELOW
1010 DATA 7, 1, 5, 3, 6, 4

21
maximum-profit/README.md Normal file
View File

@ -0,0 +1,21 @@
# Maximum profit
Puzzle from [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/the-thermometer-of-success-is-merely-the-jealousy/) newsletter, July 23rd 2023.
Implementation in ANSI BASIC with prototype in Python.
Solution posted at https://strangeobject.space/@ooze/110770674393278897
## How to run
Edit the last `DATA` statement from the `MAXPROFIT.BAS` file to specify the sequence. Update the loop counter on line
20 to the number of elements in that sequence.
Running the code requires a BASIC intepreter such as [Bywater BASIC](https://github.com/nerun/bwbasic/) (bwBASIC). For
example, on Ubuntu, Debian, or Pop! OS systems, it can be installed from `apt install bwbasic`.
```console
bwbasic MAXPROFIT.BAS
```
Exit the interactive environment by typing Ctrl-D.

View File

@ -0,0 +1,10 @@
prices = [7, 1, 5, 3, 6, 4]
buy_price = prices[0]
max_profit = max(0, prices[1] - buy_price)
for price in prices:
max_profit = max(0, max_profit, price - buy_price)
buy_price = min(buy_price, price)
print(max_profit)

View File

@ -0,0 +1,7 @@
# Length of the longest valid parenthesis substring
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/friends-and-good-manners-will-carry-you-where/) newsletter from August 14th, 2022.
> Given a string s consisting of various parenthesis ( and ), find the length of the longest valid parenthesis substring.
Solution posted at https://gist.github.com/zoeisnowooze/5347717cfd57d564518ca41e6eeff83b

View File

@ -0,0 +1,39 @@
#include <stdbool.h>
#include <stdio.h>
int main(int argc, char **argv) {
int length, maxlength, stacksize;
length = maxlength = stacksize = 0;
while (true) {
int c;
c = getc(stdin);
if (c == '\n') {
/* Remove extra left parenthesis and check if it's the longest substring. */
if (length - stacksize > maxlength) {
maxlength = length - stacksize;
}
printf("%d\n", maxlength);
length = maxlength = stacksize = 0;
} else if (c == EOF) {
putchar('\n');
break;
} else if (c == '(') {
length++;
stacksize++;
} else if (c == ')') {
stacksize--;
length++;
if (stacksize == 0 && length > maxlength) {
/* Parenthesis substring completely closed, keep length and continue counting. */
maxlength = length;
} else if (stacksize < 0) {
/* Extra closing parenthesis, reset all counters. */
length = 0;
stacksize = 0;
}
}
}
}

7
passdoors/README.md Normal file
View File

@ -0,0 +1,7 @@
# Pass doors
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/i-never-regretted-what-i-turned-down-angela/) newsletter from October 16th, 2022.
> Lets say you have n doors that start out as closed. With the first pass across the doors, you toggle every door open. With the second pass, you toggle every second door. With the third, every third door, and so on. Write a function that takes in an integer numberOfPasses, and returns how many doors are open after the number of passes.
Solution posted at https://gist.github.com/zoeisnowooze/3fd5b2f592a82a1b79be386ff3c53c3e

18
passdoors/passdoors.c Normal file
View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int number_of_doors = atoi(argv[1]);
int number_of_passes = atoi(argv[2]);
int open_doors = 0;
for (int i = 1; i <= number_of_doors; i++) {
int toggles = 0;
for (int j = 1; j <= number_of_passes; j++) {
toggles += i % j == 0 ? 1 : 0;
}
open_doors += toggles % 2;
}
printf("%d\n", open_doors);
}

21
passdoors/passdoors.py Normal file
View File

@ -0,0 +1,21 @@
import sys
def odd_number_of_divisors(n, number_of_passes):
"""Counts the number of times the door is toggled, and returns True if left open after a number of passes."""
return sum((n % i == 0 for i in range(1, number_of_passes + 1))) % 2 == 1
def pass_doors(number_of_doors, number_of_passes):
if number_of_passes > number_of_doors:
number_of_passes = number_of_doors
return sum(
(
odd_number_of_divisors(i, number_of_passes)
for i in range(1, number_of_doors + 1)
)
)
if __name__ == "__main__":
print(pass_doors(int(sys.argv[1]), int(sys.argv[2])))

View File

@ -0,0 +1,34 @@
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("passdoors", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}

View File

@ -0,0 +1,30 @@
const std = @import("std");
pub fn count_open_doors(number_of_doors: usize, number_of_passes: usize) usize {
var open_doors: usize = 0;
var i: usize = 1;
while (i <= number_of_doors) : (i += 1) {
var j: usize = 1;
var toggles: usize = 0;
while (j <= number_of_passes) : (j += 1) {
toggles += @boolToInt(i % j == 0);
}
open_doors += toggles % 2;
}
return open_doors;
}
pub fn main() !void {
const allocator = std.heap.page_allocator;
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len < 3) return error.ExpectedArgument;
const number_of_doors: usize = try std.fmt.parseInt(usize, args[1], 10);
const number_of_passes: usize = try std.fmt.parseInt(usize, args[2], 10);
const open_doors: usize = count_open_doors(number_of_doors, number_of_passes);
const stdout = std.io.getStdOut().writer();
try stdout.print("{}\n", .{open_doors});
}

7
phone-letter/README.md Normal file
View File

@ -0,0 +1,7 @@
# Phone letter
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/correction-does-much-but-encouragement-does-more/) newsletter from November 28th, 2021.
> Given a string containing digits from 2-9, return all possible letter combinations that the number could represent based on phone numbers/letters. For example, 2 could be a, b, or c, 3 could be d, e, or f, and so on.
Solution posted at https://gist.github.com/zoeisnowooze/2d4de576560cd1f340956aca424a94b0

7
pride-flag/README.md Normal file
View File

@ -0,0 +1,7 @@
# Pride flag
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/strive-to-do-better-but-dont-beat-yourself-up-for/) newsletter from June 28th, 2021.
> Make a Pride flag! You decide how and with which languages/medium.
Solution posted at https://gist.github.com/rust-play/180b75a22b96a5d92ed319c98d110a4e

7
reorder/README.md Normal file
View File

@ -0,0 +1,7 @@
# Reorder
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/reality-is-one-of-the-possibilities-i-cannot/) newsletter from October 18th, 2021.
> Given an array of objects A, and an array of indexes B, reorder the objects in array A with the given indexes in array B.
Solution posted at https://gist.github.com/zoeisnowooze/cb2f622431046c4dd126410f10023153

17
repeated-groups/README.md Normal file
View File

@ -0,0 +1,17 @@
# Repeated groups
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/like-what-you-do-and-then-you-will-do-your-best/) newsletter from February 27th, 2023.
> Given a list of numbers, return all groups of repeating consecutive numbers.
>
> Examples:
>
> ```javascript
> > repeatedGroups([1, 2, 2, 4, 5])
> [[2, 2]]
>
> > repeatedGroups([1, 1, 0, 0, 8, 4, 4, 4, 3, 2, 1, 9, 9])
> [[1, 1], [0, 0], [4, 4, 4], [9, 9]]
> ```
Solution posted at https://strangeobject.space/@ooze/109937701330608625

19
roll-dice/README.md Normal file
View File

@ -0,0 +1,19 @@
# Roll dice
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/3709/) newsletter of March 27th, 2023.
> Given a string in dice notation, return a random integer you can get by rolling those dice.
>
> ```javascript
> > rollDice('4d4') // Four 4-sided dice
> > 13
>
> > rollDice('3d20') // Three 20-sided dice
> > 28
>
> > rollDice('1d8+2d10') // One 8-sided dice, and two 10-sided dice
> > 21
> ```
Solution posted at https://strangeobject.space/@ooze/110098248197472738
Alternate Rust solution at https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8ab6422cecc9fc82a0e5017878d0b355

8
roll-dice/roll_dice.py Normal file
View File

@ -0,0 +1,8 @@
import random
def roll_dice(spec):
return sum(
sum(random.randint(1, int(a)) for _ in range(int(b))) if b else int(a)
for a, _, b in (s.partition("d") for s in spec.split("+"))
)

View File

@ -0,0 +1,28 @@
import unittest
from roll_dice import roll_dice
class TestRollDice(unittest.TestCase):
def test_constant(self):
self.assertEqual(roll_dice("1"), 1)
self.assertEqual(roll_dice("2"), 2)
def test_sum(self):
self.assertEqual(roll_dice("1+2"), 3)
def test_dice(self):
self.assertGreaterEqual(roll_dice("4d4"), 4)
self.assertLessEqual(roll_dice("4d4"), 16)
def test_dice_plus_constant(self):
self.assertGreaterEqual(roll_dice("1d4+4"), 5)
self.assertLessEqual(roll_dice("1d4+4"), 8)
def test_dice_plus_dice(self):
self.assertGreaterEqual(roll_dice("1d8+2d10"), 3)
self.assertLessEqual(roll_dice("1d8+2d10"), 28)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,7 @@
# Vertical slashes
Puzzle from the [rendezvous with cassidoo](https://buttondown.email/cassidoo/archive/normal-is-not-something-to-aspire-to-its-4437/) from November 20th, 2023.
> Write a function that takes a string of slashes (\ and /) and returns all of those slashes drawn downwards in a line connecting them.
Solution posted at https://gist.github.com/zoeisnowooze/9d302565748fe8535a25727892533b22

View File

@ -0,0 +1,23 @@
#!/bin/bash
slashes=$(sed 's/\([\/\\]\)/\1/g' <<< "$1")
while [ -n "$slashes" ]; do
slash=$(cut -c1 <<< "$slashes")
case "$slash" in
" ")
slashes=$(cut -c2- <<< "$slashes");
if [ "$(cut -c1 <<< "$slashes")" != "/" ]; then
echo -n "$slash"
fi
;;
"/")
slashes=$(cut -c2- <<< "$slashes" | sed 's/ \([\\\/]\)/\1/g')
echo "$slash"
;;
"\\")
slashes=$(cut -c2- <<< "$slashes" | sed 's/\([\\\/]\)/ \1/g')
echo "$slash"
;;
esac
done
echo