From 96ad979d3b91a1e8ba00461319f8b12931b6b5f9 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 19:43:40 +0100 Subject: README.md for week 098. --- challenge-098/abigail/README.md | 96 ++++++++++++----------------------------- 1 file changed, 27 insertions(+), 69 deletions(-) (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index e6d1c21bb0..7434a36a21 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -1,99 +1,57 @@ # Solution by Abigail -## [Ceasar Cipher](https://perlweeklychallenge.org/blog/perl-weekly-challenge-097/#TASK1) +## [Read N-characters](https://perlweeklychallenge.org/blog/perl-weekly-challenge-098/#TASK1) -You are given string `$S` containing alphabets `A..Z` only and a number `$N`. +You are given file `$FILE`. -Write a script to encrypt the given string `$S` using Caesar Cipher with -left shift of size `$N`. +Create subroutine `readN($FILE, $number)` returns the first `n`-characters +and moves the pointer to the (`n+1`)th character. ### Example ~~~~ -Input: $S = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG", $N = 3 -Output: "QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD" - -Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ -Cipher: XYZABCDEFGHIJKLMNOPQRSTUVW - -Plaintext: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG -Ciphertext: QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD +Input: Suppose the file (input.txt) contains "1234567890" +Output: + print readN("input.txt", 4); # returns "1234" + print readN("input.txt", 4); # returns "5678" + print readN("input.txt", 4); # returns "90" ~~~~ -### Note -We will be reading the plain text from STDIN, and use an option (-s) -to indicate the left shift. - ### Solutions -* [AWK](awk/ch-1.awk) -* [Bash](bash/ch-1.sh) -* [Lua](lua/ch-1.lua) -* [C](c/ch-1.c) -* [Node.js](node/ch-1.js) -* [Perl](perl/ch-1.pl) -* [Python](python/ch-1.py) -* [Ruby](ruby/ch-1.rb) ### Blog -[Perl Weekly Challenge 97: Ceasar Cipher](https://wp.me/pcxd30-nW) -## [Binary Substrings](https://perlweeklychallenge.org/blog/perl-weekly-challenge-097/#TASK2) +## [Search Insert Position](https://perlweeklychallenge.org/blog/perl-weekly-challenge-098/#TASK2) -You are given a binary string `$B` and an integer `$S`. +You are given a sorted array of distinct integers `@N` and a target `$N`. -Write a script to split the binary string `$B` of size `$S` and then -find the minimum number of flips required to make it all the same. +Write a script to return the index of the given target if found +otherwise place the target in the sorted array and return the index. ### Examples #### Example 1 ~~~~ -Input: $B = "101100101" $S = 3 -Output: 1 - -Binary Substrings: - "101": 0 flip - "100": 1 flip to make it "101" - "101": 0 flip +Input: @N = (1, 2, 3, 4) and $N = 3 +Output: 2 since the target 3 is in the array at the index 2. ~~~~ #### Example 2 ~~~~ -Input $B = "10110111", $S = 4 -Output: 2 - -Binary Substrings: - "1011": 0 flip - "0111": 2 flips to make it "1011" +Input: @N = (1, 3, 5, 7) and $N = 6 +Output: 3 since the target 6 is missing and should be placed at the index 3. ~~~~ -### Notes -We will be reading the strings from STDIN. The length of each sub string -will be passed in as an option: -s SIZE. - -To calculate the mininim number of flips required, note that we -can calculate the number of flips for each position independently; -that is, flipping a bit at position $i doesn't influence how the -number of flips required for position $j, if $i != $j. - -For each position $i, we either need to flip all the 0s to 1s, -or all the 1s to 0s. To minimize the number of flips, we count -the number of 0s in each position, and compare that with the -number of 1s in that position. Then we take the minimum of 0s -and 1s, and sum this for all positions. +#### Example 3 +~~~~ +Input: @N = (12, 14, 16, 18) and $N = 10 +Output: 0 since the target 10 is missing and should be placed at the index 0. +~~~~ -There is no need to split the input string into chunks, -we can leave it as is. The $i-th character of the $j-th section -is as position $j * $s_len + $i, where $s_len is the length -of a section. +#### Example 4 +~~~~ +Input: @N = (11, 13, 15, 17) and $N = 19 +Output: 4 since the target 19 is missing and should be placed at the index 4. +~~~~ ### Solutions -* [AWK](awk/ch-2.awk) -* [Bash](bash/ch-2.sh) -* [C](c/ch-2.c) -* [Lua](lua/ch-2.lua) -* [Node](node/ch-2.js) -* [Perl](perl/ch-2.pl) -* [Python](python/ch-2.py) -* [Ruby](ruby/ch-2.rb) ### Blog -[Perl Weekly Challenge 97: Binary Substrings](https://wp.me/pcxd30-pi) -- cgit From bb48c0dc7d588b849fc8aa2ea438579a968b8a36 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 20:22:52 +0100 Subject: Tests for week 98, part 1 --- challenge-098/abigail/t/ctest.ini | 4 ++++ challenge-098/abigail/t/example-1.txt | 1 + challenge-098/abigail/t/example-2.txt | 1 + challenge-098/abigail/t/input-1-1 | 3 +++ challenge-098/abigail/t/input-1-2 | 4 ++++ challenge-098/abigail/t/input-1-3 | 4 ++++ challenge-098/abigail/t/output-1-1.exp | 3 +++ challenge-098/abigail/t/output-1-2.exp | 4 ++++ challenge-098/abigail/t/output-1-3.exp | 4 ++++ 9 files changed, 28 insertions(+) create mode 100644 challenge-098/abigail/t/ctest.ini create mode 100644 challenge-098/abigail/t/example-1.txt create mode 100644 challenge-098/abigail/t/example-2.txt create mode 100644 challenge-098/abigail/t/input-1-1 create mode 100644 challenge-098/abigail/t/input-1-2 create mode 100644 challenge-098/abigail/t/input-1-3 create mode 100644 challenge-098/abigail/t/output-1-1.exp create mode 100644 challenge-098/abigail/t/output-1-2.exp create mode 100644 challenge-098/abigail/t/output-1-3.exp (limited to 'challenge-098') diff --git a/challenge-098/abigail/t/ctest.ini b/challenge-098/abigail/t/ctest.ini new file mode 100644 index 0000000000..502e73267f --- /dev/null +++ b/challenge-098/abigail/t/ctest.ini @@ -0,0 +1,4 @@ +[names] +1-1 = Given example +1-2 = Different amounts +1-3 = Interleaf files diff --git a/challenge-098/abigail/t/example-1.txt b/challenge-098/abigail/t/example-1.txt new file mode 100644 index 0000000000..a32a4347a4 --- /dev/null +++ b/challenge-098/abigail/t/example-1.txt @@ -0,0 +1 @@ +1234567890 diff --git a/challenge-098/abigail/t/example-2.txt b/challenge-098/abigail/t/example-2.txt new file mode 100644 index 0000000000..72d007b6ed --- /dev/null +++ b/challenge-098/abigail/t/example-2.txt @@ -0,0 +1 @@ +ABCDEFGHIJKLMNOPQRSTUVWXYZ diff --git a/challenge-098/abigail/t/input-1-1 b/challenge-098/abigail/t/input-1-1 new file mode 100644 index 0000000000..4b650e514c --- /dev/null +++ b/challenge-098/abigail/t/input-1-1 @@ -0,0 +1,3 @@ +t/example-1.txt 4 +t/example-1.txt 4 +t/example-1.txt 4 diff --git a/challenge-098/abigail/t/input-1-2 b/challenge-098/abigail/t/input-1-2 new file mode 100644 index 0000000000..93b2127011 --- /dev/null +++ b/challenge-098/abigail/t/input-1-2 @@ -0,0 +1,4 @@ +t/example-2.txt 3 +t/example-2.txt 4 +t/example-2.txt 5 +t/example-2.txt 6 diff --git a/challenge-098/abigail/t/input-1-3 b/challenge-098/abigail/t/input-1-3 new file mode 100644 index 0000000000..f3505b0c0e --- /dev/null +++ b/challenge-098/abigail/t/input-1-3 @@ -0,0 +1,4 @@ +t/example-1.txt 3 +t/example-2.txt 4 +t/example-1.txt 2 +t/example-2.txt 1 diff --git a/challenge-098/abigail/t/output-1-1.exp b/challenge-098/abigail/t/output-1-1.exp new file mode 100644 index 0000000000..3bcb5635c2 --- /dev/null +++ b/challenge-098/abigail/t/output-1-1.exp @@ -0,0 +1,3 @@ +1234 +5678 +90 diff --git a/challenge-098/abigail/t/output-1-2.exp b/challenge-098/abigail/t/output-1-2.exp new file mode 100644 index 0000000000..3cc380de30 --- /dev/null +++ b/challenge-098/abigail/t/output-1-2.exp @@ -0,0 +1,4 @@ +ABC +DEFG +HIJKL +MNOPQR diff --git a/challenge-098/abigail/t/output-1-3.exp b/challenge-098/abigail/t/output-1-3.exp new file mode 100644 index 0000000000..174506bfa6 --- /dev/null +++ b/challenge-098/abigail/t/output-1-3.exp @@ -0,0 +1,4 @@ +123 +ABCD +45 +E -- cgit From 3018730593e223d803e8175f6eb2e23080785d7f Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 20:28:30 +0100 Subject: Perl solution for week 98, part 1 --- challenge-098/abigail/README.md | 37 +++++++++++++++++++ challenge-098/abigail/perl/ch-1.pl | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 challenge-098/abigail/perl/ch-1.pl (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index 7434a36a21..f7d65c3bb7 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -6,6 +6,43 @@ You are given file `$FILE`. Create subroutine `readN($FILE, $number)` returns the first `n`-characters and moves the pointer to the (`n+1`)th character. +### Notes + +What a poorly defined challenge. + +> You are given a file + +What does that mean? Do we get the content? A file handle? +A file descriptor? A file name? + +The example (but not the challenge itself), suggest we're getting +a file name. Ok, but....: + +> moves the pointer + +What pointer? File handles/descriptors point to something, so +then it can be argued we should leave the file handle open, +pointing to a place in the file. But we have just established we +are *not getting* a file handle -- we're getting a file name. +So, what pointer are we talking about? + +What on earth are we supposed to do? + +Are we supposed to create a file handle, and keep file handle open? +Should we just slurp in the file content, and keep a pointer +to what we have returned? + +What should happen if we call `readN` with different files, interleaved? +Keep track of where we are for each file? Restart if called with `file1`, +then `file2`, and then `file1` again? + +Our implementation will be a real stab in the dark -- we've no idea what +we are supposed to do. + +### Input +Our program will read lines from standard input; each line consists +of a filename and an amount of characters to read, separated by whitespace. + ### Example ~~~~ Input: Suppose the file (input.txt) contains "1234567890" diff --git a/challenge-098/abigail/perl/ch-1.pl b/challenge-098/abigail/perl/ch-1.pl new file mode 100644 index 0000000000..b0c3a4d0da --- /dev/null +++ b/challenge-098/abigail/perl/ch-1.pl @@ -0,0 +1,73 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# See ../README.md +# + +# +# Run as: perl ch-1.pl < input-file +# +# The input file will contain, on each line, a file name and an amount. +# + + +# +# What a poorly defined challenge. +# +# "You are given a file". +# +# What does that mean? Do we get the content? A file handle? +# A file descriptor? A file name? +# +# The example (but not the challenge itself), suggest we're getting +# a file name. Ok, but....: +# +# "moves the pointer" +# +# What pointer? File handles/descriptors point to something, so +# then it can be argued we should leave the file handle open, +# pointing to a place in the file. But we have just established we +# are NOT GETTING a file handle -- we're getting a file name. +# So, what pointer are we talking about? +# +# What on earth are we supposed to do? +# +# Are we supposed to create a file handle, and keep file handle open? +# Should we just slurp in the file content, and keep a pointer +# to what we have returned? +# +# What should happen if we call 'readN' with different files, interleaved? +# Keep track of where we are for each file? Restart if called with file1, +# then file2, and then file1 again? +# +# What follows is a real stab in the dark -- I've no idea what +# we are supposed to do. +# + +# +# Given a filename, read its contents if called for the first time with +# that filename. Return the next $amount of characters. (Or less if we +# have exhausted the content of the file). +# +sub readN ($filename, $amount) { + state $cache; + chomp ($$cache {$filename} //= do {local (@ARGV, $/) = $filename; <>}); + substr $$cache {$filename} => 0, $amount, "" +} + +while () { + chomp; + my ($filename, $amount) = split ' '; + say readN $filename, $amount; +} + +__END__ -- cgit From 2026690ecabb7764509b7845898cb4ba2298eb99 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 20:44:47 +0100 Subject: Perl solution for week 98, part 2 --- challenge-098/abigail/README.md | 12 +++++++ challenge-098/abigail/perl/ch-2.pl | 58 ++++++++++++++++++++++++++++++++++ challenge-098/abigail/t/ctest.ini | 1 + challenge-098/abigail/t/input-2-1 | 4 +++ challenge-098/abigail/t/output-2-1.exp | 4 +++ 5 files changed, 79 insertions(+) create mode 100644 challenge-098/abigail/perl/ch-2.pl create mode 100644 challenge-098/abigail/t/input-2-1 create mode 100644 challenge-098/abigail/t/output-2-1.exp (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index f7d65c3bb7..2d3ffae7bb 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -53,6 +53,7 @@ Output: ~~~~ ### Solutions +* [Perl](perl/ch-1.pl) ### Blog @@ -89,6 +90,17 @@ Input: @N = (11, 13, 15, 17) and $N = 19 Output: 4 since the target 19 is missing and should be placed at the index 4. ~~~~ +### Notes +We could write a binary search to find the target number in the +array. This is tempting, as a binary search take O (log N). But +this is futile. We're also asked to add the target element to the +array (if not found), and adding an element in the middle of an +array takes linear time. So, worst case, we're already spending +linear time. (And to read the array, we're spending linear time +anyway). + + ### Solutions +* [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-098/abigail/perl/ch-2.pl b/challenge-098/abigail/perl/ch-2.pl new file mode 100644 index 0000000000..abe58c903d --- /dev/null +++ b/challenge-098/abigail/perl/ch-2.pl @@ -0,0 +1,58 @@ +#!/opt/perl/bin/perl + +use 5.032; + +use strict; +use warnings; +no warnings 'syntax'; + +use experimental 'signatures'; +use experimental 'lexical_subs'; + +# +# See ../README.md +# + +# +# Run as: perl ch-2.pl < input-file +# +# Each line is assumed to be a white space separated list of +# numbers. The first number is the target number (`$N`), the rest of +# the numbers is the array (`@N`). +# +# Now, we could implement a binary search to find the target in +# O (log N) time, but why bother? We need to read the array, which +# means we're already spending linear time; furthermore, we have to +# insert element if not found -- which is a worst case linear time +# operation anyway. So, we just do a linear scan. +# +# Note that we insert $N into @N by adding it to the end, and then +# sorting -- which is linear in Perl (as the list (@N, $N) is nearly +# sorted). We then use a goto to go back to the search; this is +# guaranteed to succeed. +# + +INPUT: while (<>) { + chomp; + my ($N, @N) = split ' '; + SEARCH: + for my $i (keys @N) { + if ($N == $N [$i]) { + say $i; + next INPUT; + } + } + + # + # Not found. Insert by adding to the end and sorting. + # + @N = sort {$a <=> $b} @N, $N; + + # + # Now, do the search again -- this time, it will succeed. + # + goto SEARCH; +} + + +__END__ diff --git a/challenge-098/abigail/t/ctest.ini b/challenge-098/abigail/t/ctest.ini index 502e73267f..a74eb51936 100644 --- a/challenge-098/abigail/t/ctest.ini +++ b/challenge-098/abigail/t/ctest.ini @@ -2,3 +2,4 @@ 1-1 = Given example 1-2 = Different amounts 1-3 = Interleaf files +2-1 = Given examples diff --git a/challenge-098/abigail/t/input-2-1 b/challenge-098/abigail/t/input-2-1 new file mode 100644 index 0000000000..7f2eab05e9 --- /dev/null +++ b/challenge-098/abigail/t/input-2-1 @@ -0,0 +1,4 @@ +3 1 2 3 4 +6 1 3 5 7 +10 12 14 16 18 +19 11 13 15 17 diff --git a/challenge-098/abigail/t/output-2-1.exp b/challenge-098/abigail/t/output-2-1.exp new file mode 100644 index 0000000000..c89c0bde15 --- /dev/null +++ b/challenge-098/abigail/t/output-2-1.exp @@ -0,0 +1,4 @@ +2 +3 +0 +4 -- cgit From 539905267d623f18b736a6d375360cff83ce45e9 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 21:43:35 +0100 Subject: Bash solution for week 98, part 1 --- challenge-098/abigail/README.md | 2 ++ challenge-098/abigail/bash/ch-1.sh | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 challenge-098/abigail/bash/ch-1.sh (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index 2d3ffae7bb..d550cdd363 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -53,6 +53,8 @@ Output: ~~~~ ### Solutions +* [AWK](awk/ch-1.awk) +* [Bash](bash/ch-1.sh) * [Perl](perl/ch-1.pl) ### Blog diff --git a/challenge-098/abigail/bash/ch-1.sh b/challenge-098/abigail/bash/ch-1.sh new file mode 100644 index 0000000000..ebd4353079 --- /dev/null +++ b/challenge-098/abigail/bash/ch-1.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# See ../README.md +# + +# +# Run as: bash ch-1.sh < input-file +# +# Each line of input consists of a filename and an amount +# of characters to read. +# + +# +# Create associative arrays +# +declare -A content +declare -A read + +function readN { + # + # Read arguments + # + filename=$1 + amount=$2 + + # + # First time? Then read in file. + # + if [ "${read[$filename]}" != "1" ] + then read[$filename]=1 + content[$filename]=$(<$filename) + fi + + # + # Leading $amount characters + # + r=${content[$filename]:0:$amount} + + # + # Remove $amount characters + # + content[$filename]=${content[$filename]:$amount} + + echo $r +} + + +# +# Read input, call readN +# +while read filename amount +do readN $filename $amount +done -- cgit From e1229c9533942e3eb7b552111ce6e2d2d4ab421d Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 21:45:16 +0100 Subject: Test case where we exhaust a file and call readN again. --- challenge-098/abigail/t/ctest.ini | 1 + challenge-098/abigail/t/input-1-4 | 3 +++ challenge-098/abigail/t/output-1-4.exp | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 challenge-098/abigail/t/input-1-4 create mode 100644 challenge-098/abigail/t/output-1-4.exp (limited to 'challenge-098') diff --git a/challenge-098/abigail/t/ctest.ini b/challenge-098/abigail/t/ctest.ini index a74eb51936..f7f8de83d5 100644 --- a/challenge-098/abigail/t/ctest.ini +++ b/challenge-098/abigail/t/ctest.ini @@ -2,4 +2,5 @@ 1-1 = Given example 1-2 = Different amounts 1-3 = Interleaf files +1-4 = Exhaust a file 2-1 = Given examples diff --git a/challenge-098/abigail/t/input-1-4 b/challenge-098/abigail/t/input-1-4 new file mode 100644 index 0000000000..38e4f27304 --- /dev/null +++ b/challenge-098/abigail/t/input-1-4 @@ -0,0 +1,3 @@ +t/example-1.txt 6 +t/example-1.txt 6 +t/example-1.txt 6 diff --git a/challenge-098/abigail/t/output-1-4.exp b/challenge-098/abigail/t/output-1-4.exp new file mode 100644 index 0000000000..c880decfc2 --- /dev/null +++ b/challenge-098/abigail/t/output-1-4.exp @@ -0,0 +1,3 @@ +123456 +7890 + -- cgit From 686952c9bef6e28629e4b31365aa3bc4e1b8e3d0 Mon Sep 17 00:00:00 2001 From: Abigail Date: Thu, 4 Feb 2021 21:46:20 +0100 Subject: AWK solution for week 98, part 1 --- challenge-098/abigail/awk/ch-1.awk | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 challenge-098/abigail/awk/ch-1.awk (limited to 'challenge-098') diff --git a/challenge-098/abigail/awk/ch-1.awk b/challenge-098/abigail/awk/ch-1.awk new file mode 100644 index 0000000000..ac53032a93 --- /dev/null +++ b/challenge-098/abigail/awk/ch-1.awk @@ -0,0 +1,41 @@ +#!/usr/bin/awk + +# +# See ../README.md +# + +# +# Run as: awk -f ch-1.awk < input-file +# + + +# +# If we haven't ready in the content of "filename" yet, do so, +# and store it into an array, indexed by the filename. +# +# Remove the first amount characters of the stored content, and +# return it. +# +function readN(filename, amount) { + if (!content [filename]) { + old_rs = RS + # + # We want to read the entire file, so we pick a + # character which should not be present in the file + # as the record separator. + # + RS = "\000" + getline content [filename] < filename + # + # Restore the record separator. + # + RS = old_rs + } + r = substr (content [filename], 1, amount) + content [filename] = substr (content [filename], amount + 1) + return r +} + +{ + print readN($1, $2) +} -- cgit From 9ad3b511c7ff826bfeeb646f356bb17df7e50957 Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 5 Feb 2021 02:04:24 +0100 Subject: Bash solution for week 98, part 2 --- challenge-098/abigail/README.md | 1 + challenge-098/abigail/bash/ch-2.sh | 53 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 challenge-098/abigail/bash/ch-2.sh (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index d550cdd363..3b8c4e5800 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -103,6 +103,7 @@ anyway). ### Solutions +* [Bash](bash/ch-2.sh) * [Perl](perl/ch-2.pl) ### Blog diff --git a/challenge-098/abigail/bash/ch-2.sh b/challenge-098/abigail/bash/ch-2.sh new file mode 100644 index 0000000000..2a6158d1db --- /dev/null +++ b/challenge-098/abigail/bash/ch-2.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# +# See ../README.md +# + +# +# Run as: perl ch-2.sh < input-file +# +# Each line is a challenge: first number is the target number; +# the rest of the line is the array to search in. +# + +set -f + +while read -a numbers +do target=${numbers[0]} + # + # Try to find the target, counting from 1 + # + found=-1 + for ((i = 1; i < ${#numbers[@]}; i ++)) + do if (($target == ${numbers[$i]})) + then found=$((i - 1)) + break + fi + done + # + # If found, report the position and go to the next line + # + if (($found >= 0)) + then echo $found + continue + fi + + # + # Create a new array, by sorting numbers + # + IFS=$'\n' + numbers=($(sort -n <<< "${numbers[*]}")) + unset IFS + + # + # Search for the target again + # + for ((i = 0; i < ${#numbers[@]}; i ++)) + do if (($target == ${numbers[$i]})) + then found=$i + break + fi + done + echo $found +done -- cgit From 20b322efb8bfcd4055c5f84496e54cde2db3a51a Mon Sep 17 00:00:00 2001 From: Abigail Date: Fri, 5 Feb 2021 17:07:18 +0100 Subject: C solution for week 98, part 1 --- challenge-098/abigail/README.md | 1 + challenge-098/abigail/c/ch-1.c | 220 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 challenge-098/abigail/c/ch-1.c (limited to 'challenge-098') diff --git a/challenge-098/abigail/README.md b/challenge-098/abigail/README.md index 3b8c4e5800..56e481bb08 100644 --- a/challenge-098/abigail/README.md +++ b/challenge-098/abigail/README.md @@ -55,6 +55,7 @@ Output: ### Solutions * [AWK](awk/ch-1.awk) * [Bash](bash/ch-1.sh) +* [C](c/ch-1.ch) * [Perl](perl/ch-1.pl) ### Blog diff --git a/challenge-098/abigail/c/ch-1.c b/challenge-098/abigail/c/ch-1.c new file mode 100644 index 0000000000..8aee103290 --- /dev/null +++ b/challenge-098/abigail/c/ch-1.c @@ -0,0 +1,220 @@ +# include +# include +# include +# include +# include + +/* + * See ../README.md + */ + +/* + * Run as: cc -o ch-1.o ch-1.c; ./ch-1.o < input-file + */ + +/* + * Copied from https://gist.github.com/w-vi/7e98342181776162b1a3 + */ +char * slurpfile (char * filename) { + FILE * fp; + char * source; + long bufsize; + size_t len; + if ((fp = fopen (filename, "r")) == NULL) { + fprintf (stderr, "Failed to open %s\n", filename); + exit (1); + } + /* + * Get the size of the file: + * - seek to the end of the file + * - use ftell to get the offset from the start + * - seek back to the beginning + */ + if (fseek (fp, 0L, SEEK_END) != 0) { + fprintf (stderr, "seek() failed for %s\n", filename); + exit (1); + } + if ((bufsize = ftell (fp)) == -1) { + fprintf (stderr, "ftell() failed for %s\n", filename); + exit (1); + } + if (fseek (fp, 0L, SEEK_SET) != 0) { + fprintf (stderr, "seek() failed for %s\n", filename); + exit (1); + } + + /* + * Allocate memory for content of the file + */ + if ((source = (char *) malloc (sizeof (char) * (bufsize + 1))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + + /* + * And read it in + */ + if ((len = fread (source, sizeof (char), bufsize, fp)) == 0) { + fprintf (stderr, "fread() failed for %s\n", filename); + exit (1); + } + source [++ len] = '\0'; + + return source; +} + +/* + * Use four arrays: + * - filenames: names of files read + * - content: pointers to content of files read + * - content_ptr: pointers to unreturned content + * - content_size: number of characters not returned yet + */ +size_t read_files = 0; +char ** filenames = NULL; +char ** content = NULL; +char ** content_ptr = NULL; +size_t * content_size = NULL; + +char * readN (char * filename, int amount) { + ssize_t found = -1; + char * out; + /* + * Check whether we've already found the file -- + * if so, set its position in "found". + */ + for (size_t i = 0; i < read_files; i ++) { + if (strncmp (filename, filenames [i], PATH_MAX) == 0) { + /* + * Found the file + */ + found = i; + break; + } + } + + /* + * Not found; all filename, content of file, and size to + * the end of the arrays. + */ + if (found < 0) { + found = read_files ++; + /* + * Allocate memory + */ + if ((filenames = (char **) + realloc (filenames, read_files * sizeof (char *))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + if ((content = (char **) + realloc (content, read_files * sizeof (char *))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + if ((content_ptr = (char **) + realloc (content_ptr, read_files * sizeof (char *))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + if ((content_size = (size_t *) + realloc (content_size, read_files * sizeof (size_t))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + + /* + * Set data + */ + if ((filenames [found] = (char *) + malloc (sizeof (char) * (strlen (filename) + 1))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + stpncpy (filenames [found], filename, strlen (filename)); + filenames [found] [strlen (filename)] = '\0'; + content [found] = slurpfile (filename); + content_ptr [found] = content [found]; + content_size [found] = strlen (content [found]); + + /* + * Remove any trailing new lines + */ + while (content [found] [content_size [found] - 1] == '\n') { + content [found] [-- content_size [found]] = '\0'; + } + } + /* + * Now 'found' points to the place where the content + * of the file is. + */ + + /* + * Cannot return more than we have. + */ + if (content_size [found] < amount) { + amount = content_size [found]; + } + /* + * Allocate memory for the return value + */ + if ((out = (char *) malloc (sizeof (char) * (amount + 1))) == NULL) { + fprintf (stderr, "malloc() failed for %s\n", filename); + exit (1); + } + /* + * Copy the amount of data, make sure it's NUL terminated. + */ + stpncpy (out, content_ptr [found], amount); + out [amount] = '\0'; + + /* + * Adjust the pointer and size left + */ + content_ptr [found] += amount; + content_size [found] -= amount; + + return out; +} + + + +int main (void) { + char * line = NULL; + size_t len = 0; + size_t strlen; + + /* + * Iterate over the lines of input; parse each line into + * a file name and an amount. Call readN for each line. + */ + while ((strlen = getline (&line, &len, stdin)) != -1) { + char * line_ptr = line; + char * filename; + int amount; + if ((filename = (char *) malloc (PATH_MAX * sizeof (char))) == NULL) { + fprintf (stderr, "malloc() failed\n"); + exit (1); + } + if (sscanf (line_ptr, "%s %d", filename, &amount) != 2) { + fprintf (stderr, "Could not parse input\n"); + exit (1); + } + printf ("%s\n", readN (filename, amount)); + free (filename); + } + /* + * Release memory + */ + free (line); + for (size_t i = 0; i < read_files; i ++) { + free (filenames [i]); + free (content [i]); + } + free (filenames); + free (content); + free (content_ptr); + free (content_size); + + return (0); +} -- cgit From fe7759f1063d132eb4fe234f95cc25b7d924b6dd Mon Sep 17 00:00:00 2001 From: Abigail Date: Sun, 7 Feb 2021 22:33:47 +0100 Subject: Lua solution for week 98, part 1 --- challenge-098/abigail/lua/ch-1.lua | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 challenge-098/abigail/lua/ch-1.lua (limited to 'challenge-098') diff --git a/challenge-098/abigail/lua/ch-1.lua b/challenge-098/abigail/lua/ch-1.lua new file mode 100644 index 0000000000..4c8a8a4c92 --- /dev/null +++ b/challenge-098/abigail/lua/ch-1.lua @@ -0,0 +1,34 @@ +#!/opt/local/bin/lua + +-- +-- See ../README.md +-- + +-- +-- Run as: lua ch-1.lua < input-file +-- + +local content = {}; + +function readN (filename, amount) + if content [filename] == nil + then -- + -- Read the content of the file, strip the trailing + -- newline, and store the content in the table 'content' + -- + content [filename] = assert (io . open (filename, "r")) : + read ("*all") : + gsub ("\n$", "") + end + local out = content [filename] : sub (1, amount) + content [filename] = content [filename] : sub (amount + 1) + return out +end + +for line in io . lines () do + -- + -- Split the line on whitespace, call readN() with the + -- result, and print the return value of readN(). + -- + print (readN (line : match ("(%S+) (%S+)"))) +end -- cgit