aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeadmarshal <adeadmarshal@gmail.com>2025-02-10 14:59:57 +0330
committerdeadmarshal <adeadmarshal@gmail.com>2025-02-10 14:59:57 +0330
commit9cdf26f0f3ef3cedb981c930707230ed2a7ff754 (patch)
treeb28d5231ef6904ad60a1f4373ee53a69b5699489
parentaa4b8399bdb3da0a50173fcab689bfa80b9b54e1 (diff)
downloadperlweeklychallenge-club-9cdf26f0f3ef3cedb981c930707230ed2a7ff754.tar.gz
perlweeklychallenge-club-9cdf26f0f3ef3cedb981c930707230ed2a7ff754.tar.bz2
perlweeklychallenge-club-9cdf26f0f3ef3cedb981c930707230ed2a7ff754.zip
TWC308
-rw-r--r--challenge-308/deadmarshal/blog.txt1
-rw-r--r--challenge-308/deadmarshal/java/Ch1.java19
-rw-r--r--challenge-308/deadmarshal/java/Ch2.java16
-rw-r--r--challenge-308/deadmarshal/modula-3/Ch1/src/Ch1.m340
-rw-r--r--challenge-308/deadmarshal/modula-3/Ch1/src/m3makefile4
-rw-r--r--challenge-308/deadmarshal/modula-3/Ch2/src/Ch2.m337
-rw-r--r--challenge-308/deadmarshal/modula-3/Ch2/src/m3makefile4
-rw-r--r--challenge-308/deadmarshal/perl/ch-1.pl17
-rw-r--r--challenge-308/deadmarshal/perl/ch-2.pl14
-rw-r--r--challenge-308/deadmarshal/sml/ch1.sml22
-rw-r--r--challenge-308/deadmarshal/sml/ch2.sml15
-rw-r--r--challenge-308/deadmarshal/zig/ch1/build.zig91
-rw-r--r--challenge-308/deadmarshal/zig/ch1/build.zig.zon72
-rw-r--r--challenge-308/deadmarshal/zig/ch1/src/main.zig54
-rw-r--r--challenge-308/deadmarshal/zig/ch1/src/root.zig10
-rw-r--r--challenge-308/deadmarshal/zig/ch2/build.zig91
-rw-r--r--challenge-308/deadmarshal/zig/ch2/build.zig.zon72
-rw-r--r--challenge-308/deadmarshal/zig/ch2/src/main.zig38
-rw-r--r--challenge-308/deadmarshal/zig/ch2/src/root.zig10
19 files changed, 627 insertions, 0 deletions
diff --git a/challenge-308/deadmarshal/blog.txt b/challenge-308/deadmarshal/blog.txt
new file mode 100644
index 0000000000..64bd194495
--- /dev/null
+++ b/challenge-308/deadmarshal/blog.txt
@@ -0,0 +1 @@
+https://deadmarshal.blogspot.com/2025/02/twc308.html
diff --git a/challenge-308/deadmarshal/java/Ch1.java b/challenge-308/deadmarshal/java/Ch1.java
new file mode 100644
index 0000000000..fd4b1a4140
--- /dev/null
+++ b/challenge-308/deadmarshal/java/Ch1.java
@@ -0,0 +1,19 @@
+import java.util.Arrays;
+
+public class Ch1 {
+ public static void main(String[] args) {
+ System.out.println(count_common(new String[]{"perl", "weekly", "challenge"},
+ new String[]{"raku", "weekly", "challenge"}));
+ System.out.println(count_common(new String[]{"perl", "raku", "python"},
+ new String[]{"python", "java"}));
+ System.out.println(count_common(new String[]{"guest", "contribution"},
+ new String[]{"fun", "weekly", "challenge"}));
+ }
+
+ private static int count_common(String[] strs1, String[] strs2) {
+ return (int) Arrays.stream(strs1)
+ .distinct()
+ .filter(x -> Arrays.stream(strs2).anyMatch(y -> y == x))
+ .count();
+ }
+}
diff --git a/challenge-308/deadmarshal/java/Ch2.java b/challenge-308/deadmarshal/java/Ch2.java
new file mode 100644
index 0000000000..115480247c
--- /dev/null
+++ b/challenge-308/deadmarshal/java/Ch2.java
@@ -0,0 +1,16 @@
+import java.util.Arrays;
+
+public class Ch2 {
+ public static void main(String[] args) {
+ System.out.println(Arrays.toString(decode_xor(new int[]{1, 2, 3}, 1)));
+ System.out.println(Arrays.toString(decode_xor(new int[]{6, 2, 7, 3}, 4)));
+ }
+
+ private static int[] decode_xor(int[] arr, int first) {
+ int[] res = new int[arr.length + 1];
+ res[0] = first;
+ for (int i = 0; i < arr.length; ++i)
+ res[i + 1] = res[i] ^ arr[i];
+ return res;
+ }
+}
diff --git a/challenge-308/deadmarshal/modula-3/Ch1/src/Ch1.m3 b/challenge-308/deadmarshal/modula-3/Ch1/src/Ch1.m3
new file mode 100644
index 0000000000..dbab5d52dd
--- /dev/null
+++ b/challenge-308/deadmarshal/modula-3/Ch1/src/Ch1.m3
@@ -0,0 +1,40 @@
+MODULE Ch1 EXPORTS Main;
+
+IMPORT SIO,TextIntTbl;
+
+VAR
+ A1 := ARRAY[0..2] OF TEXT{"perl","weekly","challenge"};
+ A2 := ARRAY[0..2] OF TEXT{"raku","weekly","challenge"};
+ A3 := ARRAY[0..2] OF TEXT{"perl","raku","python"};
+ A4 := ARRAY[0..1] OF TEXT{"python","java"};
+ A5 := ARRAY[0..1] OF TEXT{"guest","contribution"};
+ A6 := ARRAY[0..2] OF TEXT{"fun","weekly","challenge"};
+
+PROCEDURE CountCommon(VAR A1,A2:ARRAY OF TEXT):CARDINAL =
+ VAR
+ H := NEW(TextIntTbl.Default).init(NUMBER(A1));
+ It:TextIntTbl.Iterator;
+ K:TEXT := "";
+ Count,V:INTEGER;
+ BEGIN
+ FOR I := FIRST(A1) TO LAST(A1) DO
+ IF NOT H.get(A1[I],V) THEN EVAL H.put(A1[I],1)
+ ELSE EVAL H.put(A1[I],V+1)
+ END
+ END;
+ FOR I := FIRST(A2) TO LAST(A2) DO
+ IF NOT H.get(A2[I],V) THEN EVAL H.put(A2[I],1)
+ ELSE EVAL H.put(A2[I],V+1)
+ END
+ END;
+ It := H.iterate();
+ WHILE It.next(K,V) DO IF V >= 2 THEN INC(Count) END END;
+ RETURN Count
+ END CountCommon;
+
+BEGIN
+ SIO.PutInt(CountCommon(A1,A2)); SIO.Nl();
+ SIO.PutInt(CountCommon(A3,A4)); SIO.Nl();
+ SIO.PutInt(CountCommon(A5,A6)); SIO.Nl()
+END Ch1.
+
diff --git a/challenge-308/deadmarshal/modula-3/Ch1/src/m3makefile b/challenge-308/deadmarshal/modula-3/Ch1/src/m3makefile
new file mode 100644
index 0000000000..643b33d043
--- /dev/null
+++ b/challenge-308/deadmarshal/modula-3/Ch1/src/m3makefile
@@ -0,0 +1,4 @@
+import("libm3")
+import("libsio")
+implementation("Ch1")
+program("Ch1")
diff --git a/challenge-308/deadmarshal/modula-3/Ch2/src/Ch2.m3 b/challenge-308/deadmarshal/modula-3/Ch2/src/Ch2.m3
new file mode 100644
index 0000000000..c89567b078
--- /dev/null
+++ b/challenge-308/deadmarshal/modula-3/Ch2/src/Ch2.m3
@@ -0,0 +1,37 @@
+MODULE Ch2 EXPORTS Main;
+
+IMPORT SIO,Word;
+
+TYPE
+ PArr = REF ARRAY OF INTEGER;
+
+VAR
+ A1 := ARRAY[0..2] OF INTEGER{1,2,3};
+ A2 := ARRAY[0..3] OF INTEGER{6,2,7,3};
+
+PROCEDURE DecodeXor(VAR A:ARRAY OF INTEGER;
+ READONLY First:INTEGER):PArr =
+ VAR
+ Res := NEW(PArr,NUMBER(A)+1);
+ BEGIN
+ Res[0] := First;
+ FOR I := FIRST(A) TO LAST(A) DO
+ Res[I+1] := Word.Xor(Res[I],A[I])
+ END;
+ RETURN Res
+ END DecodeXor;
+
+PROCEDURE PrintArray(VAR A:ARRAY OF INTEGER) =
+ BEGIN
+ FOR I := FIRST(A) TO LAST(A) DO
+ SIO.PutInt(A[I]);
+ SIO.PutChar(' ')
+ END;
+ SIO.Nl()
+ END PrintArray;
+
+BEGIN
+ PrintArray(DecodeXor(A1,1)^);
+ PrintArray(DecodeXor(A2,4)^);
+END Ch2.
+
diff --git a/challenge-308/deadmarshal/modula-3/Ch2/src/m3makefile b/challenge-308/deadmarshal/modula-3/Ch2/src/m3makefile
new file mode 100644
index 0000000000..78802242fe
--- /dev/null
+++ b/challenge-308/deadmarshal/modula-3/Ch2/src/m3makefile
@@ -0,0 +1,4 @@
+import("libm3")
+import("libsio")
+implementation("Ch2")
+program("Ch2")
diff --git a/challenge-308/deadmarshal/perl/ch-1.pl b/challenge-308/deadmarshal/perl/ch-1.pl
new file mode 100644
index 0000000000..678dfeb957
--- /dev/null
+++ b/challenge-308/deadmarshal/perl/ch-1.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+sub count_common{
+ my %h;
+ $h{$_}++ for @{$_[0]};
+ scalar grep{exists $h{$_} && $h{$_}++ < 2} @{$_[1]}
+}
+
+printf "%d\n",count_common(['perl','weekly','challenge'],
+ ['raku','weekly','challenge']);
+printf "%d\n",count_common(['perl','raku','python'],
+ ['python','java']);
+printf "%d\n",count_common(['guest','contribution'],
+ ['fun','weekly','challenge']);
+
diff --git a/challenge-308/deadmarshal/perl/ch-2.pl b/challenge-308/deadmarshal/perl/ch-2.pl
new file mode 100644
index 0000000000..bc763b45aa
--- /dev/null
+++ b/challenge-308/deadmarshal/perl/ch-2.pl
@@ -0,0 +1,14 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Data::Show;
+
+sub decode_xor{
+ my @res = ($_[1]);
+ push @res,$res[-1] ^ $_ foreach @{$_[0]};
+ @res
+}
+
+print show decode_xor([1,2,3],1);
+print show decode_xor([6,2,7,3],4);
+
diff --git a/challenge-308/deadmarshal/sml/ch1.sml b/challenge-308/deadmarshal/sml/ch1.sml
new file mode 100644
index 0000000000..91bee49387
--- /dev/null
+++ b/challenge-308/deadmarshal/sml/ch1.sml
@@ -0,0 +1,22 @@
+fun member _ [] = false
+ | member x (y::ys) = (x=y) orelse member x ys
+
+fun intersect([],ys) = []
+ | intersect(x::xs,ys) =
+ if member x ys then x::intersect(xs,ys)
+ else intersect(xs,ys)
+
+fun countCommon (xs,ys) =
+ length (intersect(xs,ys))
+
+val l1 = ["perl","weekly","challenge"];
+val l2 = ["raku","weekly","challenge"];
+val l3 = ["perl","raku","python"];
+val l4 = ["python","java"];
+val l5 = ["guest","contribution"];
+val l6 = ["fun","weekly","challenge"];
+
+countCommon (l1,l2);
+countCommon (l3,l4);
+countCommon (l5,l6);
+
diff --git a/challenge-308/deadmarshal/sml/ch2.sml b/challenge-308/deadmarshal/sml/ch2.sml
new file mode 100644
index 0000000000..1a59e88d12
--- /dev/null
+++ b/challenge-308/deadmarshal/sml/ch2.sml
@@ -0,0 +1,15 @@
+fun decodeXor xs first =
+ let fun aux _ [] acc = List.rev acc
+ | aux first (x::xs) acc =
+ let val t = Word.xorb (Word.fromInt (List.hd acc),
+ Word.fromInt x)
+ in
+ aux first xs (Word.toInt(t) :: acc)
+ end
+ in
+ aux first xs [first]
+ end;
+
+decodeXor [1,2,3] 1;
+decodeXor [6,2,7,3] 4;
+
diff --git a/challenge-308/deadmarshal/zig/ch1/build.zig b/challenge-308/deadmarshal/zig/ch1/build.zig
new file mode 100644
index 0000000000..3a545f1f98
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch1/build.zig
@@ -0,0 +1,91 @@
+const std = @import("std");
+
+// Although this function looks imperative, note that its job is to
+// declaratively construct a build graph that will be executed by an external
+// runner.
+pub fn build(b: *std.Build) 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 optimization options allow the person running `zig build` to select
+ // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
+ // set a preferred release mode, allowing the user to decide how to optimize.
+ const optimize = b.standardOptimizeOption(.{});
+
+ const lib = b.addStaticLibrary(.{
+ .name = "ch1",
+ // In this case the main source file is merely a path, however, in more
+ // complicated build scripts, this could be a generated file.
+ .root_source_file = b.path("src/root.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ // This declares intent for the library to be installed into the standard
+ // location when the user invokes the "install" step (the default step when
+ // running `zig build`).
+ b.installArtifact(lib);
+
+ const exe = b.addExecutable(.{
+ .name = "ch1",
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ // This declares intent for the executable to be installed into the
+ // standard location when the user invokes the "install" step (the default
+ // step when running `zig build`).
+ b.installArtifact(exe);
+
+ // This *creates* a Run step in the build graph, to be executed when another
+ // step is evaluated that depends on it. The next line below will establish
+ // such a dependency.
+ const run_cmd = b.addRunArtifact(exe);
+
+ // By making the run step depend on the install step, it will be run from the
+ // installation directory rather than directly from within the cache directory.
+ // This is not necessary, however, if the application depends on other installed
+ // files, this ensures they will be present and in the expected location.
+ run_cmd.step.dependOn(b.getInstallStep());
+
+ // This allows the user to pass arguments to the application in the build
+ // command itself, like this: `zig build run -- arg1 arg2 etc`
+ if (b.args) |args| {
+ run_cmd.addArgs(args);
+ }
+
+ // This creates a build step. It will be visible in the `zig build --help` menu,
+ // and can be selected like this: `zig build run`
+ // This will evaluate the `run` step rather than the default, which is "install".
+ const run_step = b.step("run", "Run the app");
+ run_step.dependOn(&run_cmd.step);
+
+ // Creates a step for unit testing. This only builds the test executable
+ // but does not run it.
+ const lib_unit_tests = b.addTest(.{
+ .root_source_file = b.path("src/root.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
+
+ const exe_unit_tests = b.addTest(.{
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
+
+ // Similar to creating the run step earlier, this exposes a `test` step to
+ // the `zig build --help` menu, providing a way for the user to request
+ // running the unit tests.
+ const test_step = b.step("test", "Run unit tests");
+ test_step.dependOn(&run_lib_unit_tests.step);
+ test_step.dependOn(&run_exe_unit_tests.step);
+}
diff --git a/challenge-308/deadmarshal/zig/ch1/build.zig.zon b/challenge-308/deadmarshal/zig/ch1/build.zig.zon
new file mode 100644
index 0000000000..a98b632533
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch1/build.zig.zon
@@ -0,0 +1,72 @@
+.{
+ // This is the default name used by packages depending on this one. For
+ // example, when a user runs `zig fetch --save <url>`, this field is used
+ // as the key in the `dependencies` table. Although the user can choose a
+ // different name, most users will stick with this provided value.
+ //
+ // It is redundant to include "zig" in this name because it is already
+ // within the Zig package namespace.
+ .name = "ch1",
+
+ // This is a [Semantic Version](https://semver.org/).
+ // In a future version of Zig it will be used for package deduplication.
+ .version = "0.0.0",
+
+ // This field is optional.
+ // This is currently advisory only; Zig does not yet do anything
+ // with this value.
+ //.minimum_zig_version = "0.11.0",
+
+ // This field is optional.
+ // Each dependency must either provide a `url` and `hash`, or a `path`.
+ // `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
+ // Once all dependencies are fetched, `zig build` no longer requires
+ // internet connectivity.
+ .dependencies = .{
+ // See `zig fetch --save <url>` for a command-line interface for adding dependencies.
+ //.example = .{
+ // // When updating this field to a new URL, be sure to delete the corresponding
+ // // `hash`, otherwise you are communicating that you expect to find the old hash at
+ // // the new URL.
+ // .url = "https://example.com/foo.tar.gz",
+ //
+ // // This is computed from the file contents of the directory of files that is
+ // // obtained after fetching `url` and applying the inclusion rules given by
+ // // `paths`.
+ // //
+ // // This field is the source of truth; packages do not come from a `url`; they
+ // // come from a `hash`. `url` is just one of many possible mirrors for how to
+ // // obtain a package matching this `hash`.
+ // //
+ // // Uses the [multihash](https://multiformats.io/multihash/) format.
+ // .hash = "...",
+ //
+ // // When this is provided, the package is found in a directory relative to the
+ // // build root. In this case the package's hash is irrelevant and therefore not
+ // // computed. This field and `url` are mutually exclusive.
+ // .path = "foo",
+
+ // // When this is set to `true`, a package is declared to be lazily
+ // // fetched. This makes the dependency only get fetched if it is
+ // // actually used.
+ // .lazy = false,
+ //},
+ },
+
+ // Specifies the set of files and directories that are included in this package.
+ // Only files and directories listed here are included in the `hash` that
+ // is computed for this package. Only files listed here will remain on disk
+ // when using the zig package manager. As a rule of thumb, one should list
+ // files required for compilation plus any license(s).
+ // Paths are relative to the build root. Use the empty string (`""`) to refer to
+ // the build root itself.
+ // A directory listed here means that all files within, recursively, are included.
+ .paths = .{
+ "build.zig",
+ "build.zig.zon",
+ "src",
+ // For example...
+ //"LICENSE",
+ //"README.md",
+ },
+}
diff --git a/challenge-308/deadmarshal/zig/ch1/src/main.zig b/challenge-308/deadmarshal/zig/ch1/src/main.zig
new file mode 100644
index 0000000000..249b714db7
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch1/src/main.zig
@@ -0,0 +1,54 @@
+const std = @import("std");
+
+fn countCommon(
+ allocator: std.mem.Allocator,
+ a1: []const []const u8,
+ a2: []const []const u8,
+) !usize {
+ var count: usize = 0;
+ var h = std.StringHashMap(u32).init(allocator);
+ defer h.deinit();
+ for (a1) |s| {
+ const entry = try h.getOrPut(s);
+ if (entry.found_existing) {
+ entry.value_ptr.* += 1;
+ } else {
+ entry.value_ptr.* = 1;
+ }
+ }
+ for (a2) |s| {
+ const entry = try h.getOrPut(s);
+ if (entry.found_existing) {
+ entry.value_ptr.* += 1;
+ } else {
+ entry.value_ptr.* = 1;
+ }
+ }
+ var it = h.iterator();
+ while (it.next()) |e| {
+ if (e.value_ptr.* >= 2) {
+ count += 1;
+ }
+ }
+ return count;
+}
+
+pub fn main() !void {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer {
+ std.debug.assert(gpa.detectLeaks() == false);
+ std.debug.assert(gpa.deinit() == .ok);
+ }
+ const allocator = gpa.allocator();
+
+ const a1 = [_][]const u8{ "perl", "weekly", "challenge" };
+ const a2 = [_][]const u8{ "raku", "weekly", "challenge" };
+ const a3 = [_][]const u8{ "perl", "raku", "python" };
+ const a4 = [_][]const u8{ "python", "java" };
+ const a5 = [_][]const u8{ "guest", "contribution" };
+ const a6 = [_][]const u8{ "fun", "weekly", "challenge" };
+
+ std.debug.print("{}\n", .{try countCommon(allocator, &a1, &a2)});
+ std.debug.print("{}\n", .{try countCommon(allocator, &a3, &a4)});
+ std.debug.print("{}\n", .{try countCommon(allocator, &a5, &a6)});
+}
diff --git a/challenge-308/deadmarshal/zig/ch1/src/root.zig b/challenge-308/deadmarshal/zig/ch1/src/root.zig
new file mode 100644
index 0000000000..ecfeade1a3
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch1/src/root.zig
@@ -0,0 +1,10 @@
+const std = @import("std");
+const testing = std.testing;
+
+export fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
+
+test "basic add functionality" {
+ try testing.expect(add(3, 7) == 10);
+}
diff --git a/challenge-308/deadmarshal/zig/ch2/build.zig b/challenge-308/deadmarshal/zig/ch2/build.zig
new file mode 100644
index 0000000000..9a44c64cdc
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch2/build.zig
@@ -0,0 +1,91 @@
+const std = @import("std");
+
+// Although this function looks imperative, note that its job is to
+// declaratively construct a build graph that will be executed by an external
+// runner.
+pub fn build(b: *std.Build) 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 optimization options allow the person running `zig build` to select
+ // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
+ // set a preferred release mode, allowing the user to decide how to optimize.
+ const optimize = b.standardOptimizeOption(.{});
+
+ const lib = b.addStaticLibrary(.{
+ .name = "ch2",
+ // In this case the main source file is merely a path, however, in more
+ // complicated build scripts, this could be a generated file.
+ .root_source_file = b.path("src/root.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ // This declares intent for the library to be installed into the standard
+ // location when the user invokes the "install" step (the default step when
+ // running `zig build`).
+ b.installArtifact(lib);
+
+ const exe = b.addExecutable(.{
+ .name = "ch2",
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ // This declares intent for the executable to be installed into the
+ // standard location when the user invokes the "install" step (the default
+ // step when running `zig build`).
+ b.installArtifact(exe);
+
+ // This *creates* a Run step in the build graph, to be executed when another
+ // step is evaluated that depends on it. The next line below will establish
+ // such a dependency.
+ const run_cmd = b.addRunArtifact(exe);
+
+ // By making the run step depend on the install step, it will be run from the
+ // installation directory rather than directly from within the cache directory.
+ // This is not necessary, however, if the application depends on other installed
+ // files, this ensures they will be present and in the expected location.
+ run_cmd.step.dependOn(b.getInstallStep());
+
+ // This allows the user to pass arguments to the application in the build
+ // command itself, like this: `zig build run -- arg1 arg2 etc`
+ if (b.args) |args| {
+ run_cmd.addArgs(args);
+ }
+
+ // This creates a build step. It will be visible in the `zig build --help` menu,
+ // and can be selected like this: `zig build run`
+ // This will evaluate the `run` step rather than the default, which is "install".
+ const run_step = b.step("run", "Run the app");
+ run_step.dependOn(&run_cmd.step);
+
+ // Creates a step for unit testing. This only builds the test executable
+ // but does not run it.
+ const lib_unit_tests = b.addTest(.{
+ .root_source_file = b.path("src/root.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
+
+ const exe_unit_tests = b.addTest(.{
+ .root_source_file = b.path("src/main.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
+
+ // Similar to creating the run step earlier, this exposes a `test` step to
+ // the `zig build --help` menu, providing a way for the user to request
+ // running the unit tests.
+ const test_step = b.step("test", "Run unit tests");
+ test_step.dependOn(&run_lib_unit_tests.step);
+ test_step.dependOn(&run_exe_unit_tests.step);
+}
diff --git a/challenge-308/deadmarshal/zig/ch2/build.zig.zon b/challenge-308/deadmarshal/zig/ch2/build.zig.zon
new file mode 100644
index 0000000000..b3e934df68
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch2/build.zig.zon
@@ -0,0 +1,72 @@
+.{
+ // This is the default name used by packages depending on this one. For
+ // example, when a user runs `zig fetch --save <url>`, this field is used
+ // as the key in the `dependencies` table. Although the user can choose a
+ // different name, most users will stick with this provided value.
+ //
+ // It is redundant to include "zig" in this name because it is already
+ // within the Zig package namespace.
+ .name = "ch2",
+
+ // This is a [Semantic Version](https://semver.org/).
+ // In a future version of Zig it will be used for package deduplication.
+ .version = "0.0.0",
+
+ // This field is optional.
+ // This is currently advisory only; Zig does not yet do anything
+ // with this value.
+ //.minimum_zig_version = "0.11.0",
+
+ // This field is optional.
+ // Each dependency must either provide a `url` and `hash`, or a `path`.
+ // `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
+ // Once all dependencies are fetched, `zig build` no longer requires
+ // internet connectivity.
+ .dependencies = .{
+ // See `zig fetch --save <url>` for a command-line interface for adding dependencies.
+ //.example = .{
+ // // When updating this field to a new URL, be sure to delete the corresponding
+ // // `hash`, otherwise you are communicating that you expect to find the old hash at
+ // // the new URL.
+ // .url = "https://example.com/foo.tar.gz",
+ //
+ // // This is computed from the file contents of the directory of files that is
+ // // obtained after fetching `url` and applying the inclusion rules given by
+ // // `paths`.
+ // //
+ // // This field is the source of truth; packages do not come from a `url`; they
+ // // come from a `hash`. `url` is just one of many possible mirrors for how to
+ // // obtain a package matching this `hash`.
+ // //
+ // // Uses the [multihash](https://multiformats.io/multihash/) format.
+ // .hash = "...",
+ //
+ // // When this is provided, the package is found in a directory relative to the
+ // // build root. In this case the package's hash is irrelevant and therefore not
+ // // computed. This field and `url` are mutually exclusive.
+ // .path = "foo",
+
+ // // When this is set to `true`, a package is declared to be lazily
+ // // fetched. This makes the dependency only get fetched if it is
+ // // actually used.
+ // .lazy = false,
+ //},
+ },
+
+ // Specifies the set of files and directories that are included in this package.
+ // Only files and directories listed here are included in the `hash` that
+ // is computed for this package. Only files listed here will remain on disk
+ // when using the zig package manager. As a rule of thumb, one should list
+ // files required for compilation plus any license(s).
+ // Paths are relative to the build root. Use the empty string (`""`) to refer to
+ // the build root itself.
+ // A directory listed here means that all files within, recursively, are included.
+ .paths = .{
+ "build.zig",
+ "build.zig.zon",
+ "src",
+ // For example...
+ //"LICENSE",
+ //"README.md",
+ },
+}
diff --git a/challenge-308/deadmarshal/zig/ch2/src/main.zig b/challenge-308/deadmarshal/zig/ch2/src/main.zig
new file mode 100644
index 0000000000..b13741cdf2
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch2/src/main.zig
@@ -0,0 +1,38 @@
+const std = @import("std");
+
+fn decodeXor(
+ allocator: std.mem.Allocator,
+ arr: []const u32,
+ first: u32,
+) ![]u32 {
+ const res = try allocator.alloc(u32, arr.len + 1);
+ errdefer allocator.free(res);
+ res[0] = first;
+ for (0..arr.len) |i| {
+ res[i + 1] = res[i] ^ arr[i];
+ }
+ return res;
+}
+
+pub fn main() !void {
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer {
+ std.debug.assert(gpa.detectLeaks() == false);
+ std.debug.assert(gpa.deinit() == .ok);
+ }
+ const allocator = gpa.allocator();
+
+ const a1: []const u32 = &.{ 1, 2, 3 };
+ const a2: []const u32 = &.{ 6, 2, 7, 3 };
+
+ const res1 = try decodeXor(allocator, a1, 1);
+ const res2 = try decodeXor(allocator, a2, 4);
+
+ std.debug.print("{any}\n", .{res1});
+ std.debug.print("{any}\n", .{res2});
+
+ defer {
+ allocator.free(res1);
+ allocator.free(res2);
+ }
+}
diff --git a/challenge-308/deadmarshal/zig/ch2/src/root.zig b/challenge-308/deadmarshal/zig/ch2/src/root.zig
new file mode 100644
index 0000000000..ecfeade1a3
--- /dev/null
+++ b/challenge-308/deadmarshal/zig/ch2/src/root.zig
@@ -0,0 +1,10 @@
+const std = @import("std");
+const testing = std.testing;
+
+export fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
+
+test "basic add functionality" {
+ try testing.expect(add(3, 7) == 10);
+}