Skip to content

Commit 9f9b2b1

Browse files
committed
Blogged 333
1 parent 2ef3d31 commit 9f9b2b1

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
layout: post
3+
title: "Weekly Challenge #333: Back in the Saddle Again"
4+
author: "Dave Jacoby"
5+
date: "2025-08-07 17:33:09 -0400"
6+
categories: ""
7+
---
8+
9+
Welcome to [_**Weekly Challenge #333!**_](https://theweeklychallenge.org/blog/perl-weekly-challenge-333/) It's been a while since I've done this. It's good to be back.
10+
11+
### Task 1: Straight Line
12+
13+
> Submitted by: Mohammad Sajid Anwar
14+
> You are given a list of co-ordinates.
15+
>
16+
> Write a script to find out if the given points make a straight line.
17+
18+
#### Let's Talk About It
19+
20+
Here's my thought: We're comparing the angle of every pair of points. We're doing the nested loop thing, and if you've done points **a** and **b** once, there's no reason to do them twice, so **b** starts at **a+1**.
21+
22+
(I'm seeing now that I could've popped the first one and compared it with every other. _C'est la vie._)
23+
24+
So, the comparison goes to angles. The angle from `0,0` to `1,1` is given by `atan2(1-0,1-0)` and is `0.785398163397448` radians or 45 degrees. Reverse the order and you get `-2.35619449019234` radians or -135 degrees. Rather than stress getting the correct order, I do both, storing them in a hash. If we get 1 key, it's `0` because it's all the same point, and that counts. If we get 2 keys, that's both directions and that counts. And if there's more, that means they're not all in the same line, and that's a false.
25+
26+
#### Show Me The Code
27+
28+
```perl
29+
#!/usr/bin/env perl
30+
31+
use strict;
32+
use warnings;
33+
use experimental qw{ say state postderef signatures };
34+
35+
my @examples = (
36+
37+
[ [ 2, 1 ], [ 2, 3 ], [ 2, 5 ] ],
38+
[ [ 1, 4 ], [ 3, 4 ], [ 10, 4 ] ],
39+
[ [ 0, 0 ], [ 1, 1 ], [ 2, 3 ] ],
40+
[ [ 1, 1 ], [ 1, 1 ], [ 1, 1 ] ],
41+
[ [ 1000000, 1000000 ], [ 2000000, 2000000 ], [ 3000000, 3000000 ] ],
42+
);
43+
44+
for my $input (@examples) {
45+
my $output = straight_line( $input->@* );
46+
my $str = join ',', map { qq{[$_]} } map { join ', ', $_->@* } $input->@*;
47+
say <<"END";
48+
Input: \@str = ($str)
49+
Output: $output
50+
END
51+
}
52+
53+
sub straight_line (@array) {
54+
my %angles;
55+
for my $i ( 0 .. $#array ) {
56+
my $k = $array[$i];
57+
for my $j ( $i + 1, $#array ) {
58+
next unless $i != $j;
59+
next unless defined $array[$j];
60+
my $l = $array[$j];
61+
my $a1 = find_angle( $k, $l );
62+
my $a2 = find_angle( $l, $k );
63+
$angles{$a1} = 1;
64+
$angles{$a2} = 1;
65+
}
66+
}
67+
return scalar keys %angles <= 2 ? 'true' : 'false';
68+
}
69+
70+
sub find_angle ( $p1, $p2 ) {
71+
return atan2(
72+
$p1->[1] - $p2->[1], $p1->[0] - $p2->[0]
73+
);
74+
}
75+
```
76+
77+
```text
78+
$ ./ch-1.pl
79+
Input: @str = ([2, 1],[2, 3],[2, 5])
80+
Output: true
81+
82+
Input: @str = ([1, 4],[3, 4],[10, 4])
83+
Output: true
84+
85+
Input: @str = ([0, 0],[1, 1],[2, 3])
86+
Output: false
87+
88+
Input: @str = ([1, 1],[1, 1],[1, 1])
89+
Output: true
90+
91+
Input: @str = ([1000000, 1000000],[2000000, 2000000],[3000000, 3000000])
92+
Output: true
93+
```
94+
95+
### Task 2: Duplicate Zeros
96+
97+
> Submitted by: Mohammad Sajid Anwar
98+
> You are given an array of integers.
99+
>
100+
> Write a script to duplicate each occurrence of zero, shifting the remaining elements to the right. The elements beyond the length of the original array are not written.
101+
102+
#### Let's Talk About It
103+
104+
This is copying an array piece by piece, except:
105+
106+
- when there's a zero, we copy it twice
107+
- we _never_ go past the length of the original array
108+
109+
I *could* handwave it, like `return @output[0..$#input]` or the like, but no, we're going to police ourselves twice: when copying `input[i]` and when adding the subsequent zero.
110+
111+
#### Show Me The Code
112+
113+
```perl
114+
#!/usr/bin/env perl
115+
116+
use strict;
117+
use warnings;
118+
use experimental qw{ say state postderef signatures };
119+
120+
my @examples = (
121+
122+
[ 1, 0, 2, 3, 0, 4, 5, 0 ],
123+
[ 1, 2, 3 ],
124+
[ 1, 2, 3, 0 ],
125+
[ 0, 0, 1, 2 ],
126+
[ 1, 2, 0, 3, 4 ],
127+
128+
);
129+
130+
for my $input (@examples) {
131+
my $str = join ',', $input->@*;
132+
my @output = duplicate_zeroes( $input->@* );
133+
my $output = join ',', @output;
134+
say <<"END";
135+
Input: \@str = ($str)
136+
Output: ($output)
137+
END
138+
}
139+
140+
sub duplicate_zeroes (@ints) {
141+
my @output;
142+
my $l = $#ints;
143+
for my $i ( 0 .. $l ) {
144+
my $n = $ints[$i];
145+
my $o = $#output;
146+
push @output, $n if $#output < $l;
147+
push @output, $n if $n == 0 && $#output < $l;
148+
}
149+
return @output;
150+
}
151+
```
152+
153+
```text
154+
$ ./ch-2.pl
155+
Input: @str = (1,0,2,3,0,4,5,0)
156+
Output: (1,0,0,2,3,0,0,4)
157+
158+
Input: @str = (1,2,3)
159+
Output: (1,2,3)
160+
161+
Input: @str = (1,2,3,0)
162+
Output: (1,2,3,0)
163+
164+
Input: @str = (0,0,1,2)
165+
Output: (0,0,0,0)
166+
167+
Input: @str = (1,2,0,3,4)
168+
Output: (1,2,0,0,3)
169+
```
170+
171+
#### If you have any questions or comments, I would be glad to hear it. Ask me on [Mastodon](https://mastodon.xyz/@jacobydave) or [make an issue on my blog repo.](https://github.com/jacoby/jacoby.github.io)

0 commit comments

Comments
 (0)