Department numbers: Difference between revisions
Content deleted Content added
Recombinant (talk | contribs) m →Creating and using an iterator: update @truncate() calls |
|||
(16 intermediate revisions by 8 users not shown) | |||
Line 198:
</pre>
=={{header|ABC}}==
{{Trans|ALGOL 68}}
<syntaxhighlight lang="abc">
PUT 7 IN max.department.number
PUT 12 IN department.sum
WRITE "police sanitation fire" /
PUT 2 IN police
WHILE police <= max.department.number:
FOR sanitation IN { 1 .. max.department.number }:
IF sanitation <> police:
PUT ( department.sum - police ) - sanitation IN fire
IF fire > 0 AND fire <= max.department.number AND fire <> sanitation AND fire <> police:
WRITE police>>6, sanitation>>11, fire>>5 /
PUT police + 2 IN police</syntaxhighlight>
{{out}}
<pre>
police sanitation fire
2 3 7
2 4 6
2 6 4
2 7 3
4 1 7
4 2 6
4 3 5
4 5 3
4 6 2
4 7 1
6 1 5
6 2 4
6 4 2
6 5 1
</pre>
=={{header|Action!}}==
Line 917 ⟶ 950:
end</syntaxhighlight>
{{out| Output}}<pre>P S F
2 3 7
2 4 6
2 6 4
2 7 3
4 1 7
4 2 6
4 3 5
4 5 3
4 6 2
4 7 1
6 1 5
6 2 4
6 4 2
6 5 1</pre>
==={{header|Run BASIC}}===
Line 2,957 ⟶ 3,005:
<pre>{{2, 3, 7}, {2, 4, 6}, {2, 6, 4}, {2, 7, 3}, {4, 1, 7}, {4, 2, 6}, {4, 3, 5}, {4, 5, 3},
{4, 6, 2}, {4, 7, 1}, {6, 1, 5}, {6, 2, 4}, {6, 4, 2}, {6, 5, 1}}</pre>
=={{header|MATLAB}}==
<syntaxhighlight lang="MATLAB">
% Execute the functions
clear all;close all;clc;
sol = findsolution();
disp(table(sol(:, 1), sol(:, 2), sol(:, 3), 'VariableNames',{'Pol.','Fire','San.'}))
function sol = findsolution()
rng = 1:7;
sol = [];
for p = rng
for f = rng
for s = rng
if p ~= s && s ~= f && f ~= p && p + s + f == 12 && mod(p, 2) == 0
sol = [sol; p s f];
end
end
end
end
end
</syntaxhighlight>
{{out}}
<pre>
Pol. Fire San.
____ ____ ____
2 7 3
2 6 4
2 4 6
2 3 7
4 7 1
4 6 2
4 5 3
4 3 5
4 2 6
4 1 7
6 5 1
6 4 2
6 2 4
6 1 5
</pre>
=={{header|MiniScript}}==
{{trans|Kotlin}}
<syntaxhighlight lang="miniscript">print "Police Sanitation Fire"
print "------ ---------- ----"
count = 0
for h in range(1, 3)
i = h * 2
for j in range(1, 7)
if j != i then
for k in range(1, 7)
if k != i and k != j and i + j + k == 12 then
print " " + i + " " + j + " " + k
count += 1
end if
end for
end if
end for
end for
print char(10) + count + " valid combinations"</syntaxhighlight>
{{out}}
<pre>Police Sanitation Fire
------ ---------- ----
2 3 7
2 4 6
2 6 4
2 7 3
4 1 7
4 2 6
4 3 5
4 5 3
4 6 2
4 7 1
6 1 5
6 2 4
6 4 2
6 5 1
14 valid combinations
</pre>
=={{header|Modula-2}}==
Line 3,051 ⟶ 3,183:
6 4 2
6 5 1</pre>
=={{header|newLISP}}==
<syntaxhighlight lang="newlisp">
(and
(println "--police-- --sanitation-- --fire--")
(dolist (lst
(filter
(fn(l) (and (= (unique l) l)
(= 12 (apply + l))
(member (l 0) '(2 4 6))
(= 2 (length (intersect (rest l)
'(1 2 3 4 5 6 7))))))
(map (fn(n) (map int (explode (string n))))
(sequence 111 777))))
(println (format " %d %d %d"
lst))))
</syntaxhighlight>
{{out}}
<pre>
--police-- --sanitation-- --fire--
2 3 7
2 4 6
2 6 4
2 7 3
4 1 7
4 2 6
4 3 5
4 5 3
4 6 2
4 7 1
6 1 5
6 2 4
6 4 2
6 5 1
</pre>
Solution 2.
Let's make the flow easier to follow by using chaining (pipelining).
Example:
Instead of saying
<syntaxhighlight lang="newlisp">(let (x 8) (list 'foo (pow 2 x) 'bar))</syntaxhighlight>
we can say:
<syntaxhighlight lang="newlisp">(=>> 8 (pow 2 ??) (list 'foo ?? 'bar))</syntaxhighlight>
{{out}}<pre>(foo 256 bar)</pre>
The order in which the functions are executed is the order in which they appear. I think that this makes the code easier to understand.
<syntaxhighlight lang="newlisp">
(define-macro (=>> _E_ _form_)
(eval
(if $args
(cons '=>> (cons (list '=>> _E_ _form_) (args)))
(begin
(if (ref '?? _form_) (setf (nth $it _form_) _E_))
_form_))))
(=>>
(begin
(println "--police-- --sanitation-- --fire--")
(sequence 111 777))
(map (fn(n) (map int (explode (string n)))) ??)
(filter
(fn(L) (and (= (unique L) L)
(= 12 (apply + L))
(even? (L 0))
(empty? (difference L '(1 2 3 4 5 6 7)))))
??)
(dolist (lst ??)
(println (format " %d %d %d"
lst))))
</syntaxhighlight>
Solution 3.
Finally rising above the brute-force approach. (It's about time.)
<syntaxhighlight lang="newlisp">
(let (nums '(1 2 3 4 5 6 7))
(for (police 2 (last nums) 2)
(dolist (sanitation (difference nums (list police)))
(let (fire (- 12 sanitation police))
(if (member fire (difference nums (list sanitation police)))
(println police '- sanitation '- fire))))))
</syntaxhighlight>
=={{header|Nim}}==
Line 3,225 ⟶ 3,442:
6 4 2
6 5 1</pre>
=={{header|PascalABC.NET}}==
<syntaxhighlight lang="delphi">
begin
Writeln('Police Fire Sanitation');
for var p := 2 to 6 step 2 do
for var f := 1 to 7 do
for var s := 1 to 7 do
if (p <> f) and (f <> s) and (p <> s) and (p + f + s = 12) then
Writeln($'{p,-8}{f,-8}{s,-8}');
end.
</syntaxhighlight>
{{out}}
<pre>
Police Fire Sanitation
2 3 7
2 4 6
2 6 4
2 7 3
4 1 7
4 2 6
4 3 5
4 5 3
4 6 2
4 7 1
6 1 5
6 2 4
6 4 2
6 5 1
</pre>
=={{header|Perl}}==
Line 4,200 ⟶ 4,447:
</pre>
=={{header|RPL}}==
≪ { }
<span style="color:red">2 6</span> '''FOR''' police
<span style="color:red">1 7</span> '''FOR''' sanitation
'''IF''' police sanitation ≠ '''THEN'''
<span style="color:red">12</span> police - sanitation -
'''IF''' DUP <span style="color:red">0</span> >
OVER <span style="color:red">7</span> ≤ AND
OVER police ≠ AND
OVER sanitation ≠ AND
'''THEN'''
police sanitation ROT
<span style="color:red">3</span> →ARRY +
'''ELSE''' DROP '''END'''
'''END'''
'''NEXT'''
<span style="color:red">2</span> '''STEP'''
DUP SIZE
≫ '<span style="color:blue">PSF</span>' STO
{{out}}
<pre>
2: { [ 2 3 7 ] [ 2 4 6 ] [ 2 6 4 ] [ 2 7 3 ] [ 4 1 7 ] [ 4 2 6 ] [ 4 3 5 ] [ 4 5 3 ] [ 4 6 2 ] [ 4 7 1 ] [ 6 1 5 ] [ 6 2 4 ] [ 6 4 2 ] [ 6 5 1 ] }
1: 14
</pre>
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">
Line 4,777 ⟶ 5,049:
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="
System.print("------ ---------- ----")
var count = 0
Line 4,872 ⟶ 5,144:
const stdout = std.io.getStdOut().writer();
var p: usize = 2;
Line 4,880 ⟶ 5,152:
for (1..7 + 1) |f|
if (p != s and s != f and f != p and p + f + s == 12) {
};
}</syntaxhighlight>
Line 4,900 ⟶ 5,172:
6 4 2
6 5 1</pre>
===
{{works with|Zig|0.11.0}}
Using a Zig ''struct'' to create an iterator is a common pattern in Zig.
<syntaxhighlight lang="zig"
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
var it = SolutionIterator
while (it.next()) |solution| {
" {d} {d} {d}\n",
.{ solution.police, solution.sanitation, solution.fire },
);
}
}
const Departments = packed struct {
police: u3,
sanitation: u3,
fire: u3,
};
const DepartmentsUnion = packed union {
departments: Departments,
together: u9,
};
const SolutionIterator = struct {
// police is initialized to one as adding one is the first operation in next()
// with the result .police == 2 (an even number) on the first pass.
u: DepartmentsUnion = .{ .departments = .{ .police = 1, .sanitation = 1, .fire = 1 } },
/// init() returns an initialised structure.
/// Using init() is a common Zig pattern.
fn init() SolutionIterator {
return SolutionIterator{};
}
fn next(self: *SolutionIterator) ?Departments {
if (self.u.together == 0) return null; // already completed
while (true) {
if (
self.
}
// None can be
if (self.u.departments.sanitation == 0) self.u.departments.sanitation = 1;
if (self.u.departments.fire == 0)
if (self.u.departments.police & 1 == 1)
continue;
// No two can be the same
if (self.u.departments.police == self.u.departments.sanitation) continue;
if (self.u.departments.sanitation == self.u.departments.fire) continue;
if (self.u.departments.fire == self.u.departments.police) continue;
// Must total twelve (maximum sum 7 + 7 + 7 = 21 requires 5 bits)
const p = @as(u5, self.u.departments.police);
const s = @as(u5, self.u.departments.sanitation);
const f = @as(u5, self.u.departments.fire);
if (p + s + f != 12)
continue;
return self.u.departments;
}
}
}
};
</syntaxhighlight>
=={{header|zkl}}==
|