Department numbers: Difference between revisions
→{{header|Javascript}}: Added an ES5 version |
→{{header|zkl}}: re-write |
||
Line 714: | Line 714: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
<lang zkl>Utils.Helpers.pickNFrom(3,[1..7].walk()) // 35 combos |
<lang zkl>Utils.Helpers.pickNFrom(3,[1..7].walk()) // 35 combos |
||
.filter(fcn(numbers){ numbers.sum(0)==12 }) |
.filter(fcn(numbers){ numbers.sum(0)==12 }) // which all sum to 12 (==5) |
||
.filter("apply","isEven") // at least one number is even |
|||
.println();</lang> |
.println();</lang> |
||
{{output}} |
{{output}} |
||
Line 722: | Line 721: | ||
L(L(1,4,7),L(1,5,6),L(2,3,7),L(2,4,6),L(3,4,5)) |
L(L(1,4,7),L(1,5,6),L(2,3,7),L(2,4,6),L(3,4,5)) |
||
</pre> |
</pre> |
||
Note: The sum of three odd numbers is odd, so a+b+c=12 means at least one even |
|||
⚫ | |||
nmber (1 even, two odd or 3 even). Futher, 2a+b=12, a,b in (2,4,6) has one |
|||
<lang zkl>ns:=Utils.Helpers.pickNFrom(3,[1..7].walk()) // 35 combos |
|||
solution: a=2,b=4 |
|||
.filter(fcn(numbers){ numbers.sum(0)==12 }) // which all sum to 12 (==5) |
|||
.filter("apply","isEven") // at least one number is even |
|||
⚫ | |||
.pump(List,Utils.Helpers.permute) // expand 5 results --> list of lists |
|||
⚫ | |||
.flatten() // ( (),()..) --> () |
|||
foreach p,f,s in ([2..7,2], [1..7], [1..7]) |
|||
.filter(fcn([(p,_,_)]){ p.isEven }); // with even first number |
|||
{ if((p!=s!=f) and p+f+s==12) println(p,"\t",f,"\t",s) }</lang> |
|||
⚫ | |||
foreach pfs in (ns){ "%d\t%d\t%d".fmt(pfs.xplode()).println() }</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Police Fire Sanitation |
Police Fire Sanitation |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
2 3 7 |
2 3 7 |
||
2 7 3 |
|||
2 4 6 |
2 4 6 |
||
2 6 4 |
2 6 4 |
||
2 7 3 |
|||
4 1 7 |
|||
⚫ | |||
4 2 6 |
4 2 6 |
||
4 5 3 |
|||
4 3 5 |
4 3 5 |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
6 2 4 |
|||
6 4 2 |
|||
⚫ | |||
</pre> |
</pre> |
Revision as of 01:00, 24 May 2017
You are encouraged to solve this task according to the task description, using any language you may know.
There is a highly organized city that has decided to assign a number to each of their departments:
- police department
- sanitation department
- fire department
Each department can have a number between 1 and 7 (inclusive).
The three department numbers are to be unique (different from each other) and must add up to the number 12.
The Chief of the Police doesn't like odd numbers and wants to have an even number for his department.
- Task
Write a program which outputs all valid combinations.
Possible output:
1 2 9
5 3 4
AppleScript
Composing a solution from generic functions.
<lang AppleScript>-- NUMBERING CONSTRAINTS ------------------------------------------------------
-- options :: Int -> Int -> Int -> [(Int, Int, Int)] on options(lo, hi, total)
set ds to enumFromTo(lo, hi) -- X IS EVEN script Xeven on |λ|(x) -- Y IS NOT X script Ydistinct on |λ|(y) -- Z IS IN RANGE script ZinRange on |λ|(z) if y ≠ z and lo ≤ z and z ≤ hi then Template:X, y, z else {} end if end |λ| end script concatMap(ZinRange, {total - (x + y)}) -- In range end |λ| end script script notX on |λ|(d) d ≠ x end |λ| end script concatMap(Ydistinct, filter(notX, ds)) -- Not X end |λ| end script concatMap(Xeven, filter(my even, ds)) -- Even
end options
-- TEST -----------------------------------------------------------------------
on run
set xs to options(1, 7, 12) intercalate("\n\n", ¬ {"(Police, Sanitation, Fire)", ¬ unlines(map(show, xs)), ¬ "Number of options: " & |length|(xs)})
end run
-- GENERIC FUNCTIONS ----------------------------------------------------------
-- concatMap :: (a -> [b]) -> [a] -> [b] on concatMap(f, xs)
set lst to {} set lng to length of xs tell mReturn(f) repeat with i from 1 to lng set lst to (lst & |λ|(contents of item i of xs, i, xs)) end repeat end tell return lst
end concatMap
-- enumFromTo :: Int -> Int -> [Int] on enumFromTo(m, n)
if n < m then set d to -1 else set d to 1 end if set lst to {} repeat with i from m to n by d set end of lst to i end repeat return lst
end enumFromTo
-- even :: Int -> Bool on even(x)
x mod 2 = 0
end even
-- filter :: (a -> Bool) -> [a] -> [a] on filter(f, xs)
tell mReturn(f) set lst to {} set lng to length of xs repeat with i from 1 to lng set v to item i of xs if |λ|(v, i, xs) then set end of lst to v end repeat return lst end tell
end filter
-- intercalate :: Text -> [Text] -> Text on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText} set strJoined to lstText as text set my text item delimiters to dlm return strJoined
end intercalate
-- length :: [a] -> Int on |length|(xs)
length of xs
end |length|
-- map :: (a -> b) -> [a] -> [b] on map(f, xs)
tell mReturn(f) set lng to length of xs set lst to {} repeat with i from 1 to lng set end of lst to |λ|(item i of xs, i, xs) end repeat return lst end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Script on mReturn(f)
if class of f is script then f else script property |λ| : f end script end if
end mReturn
-- show :: a -> String on show(e)
set c to class of e if c = list then script serialized on |λ|(v) show(v) end |λ| end script "[" & intercalate(", ", map(serialized, e)) & "]" else if c = record then script showField on |λ|(kv) set {k, ev} to kv "\"" & k & "\":" & show(ev) end |λ| end script "{" & intercalate(", ", ¬ map(showField, zip(allKeys(e), allValues(e)))) & "}" else if c = date then "\"" & iso8601Z(e) & "\"" else if c = text then "\"" & e & "\"" else if (c = integer or c = real) then e as text else if c = class then "null" else try e as text on error ("«" & c as text) & "»" end try end if
end show
-- unlines :: [String] -> String on unlines(xs)
intercalate(linefeed, xs)
end unlines</lang>
- Output:
(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] Number of options: 14
C++
<lang cpp>
- include <iostream>
- include <iomanip>
int main( int argc, char* argv[] ) {
int sol = 1; std::cout << "\t\tFIRE\t\tPOLICE\t\tSANITATION\n"; for( int f = 1; f < 8; f++ ) { for( int p = 1; p < 8; p++ ) { for( int s = 1; s < 8; s++ ) { if( f != p && f != s && p != s && !( p & 1 ) && ( f + s + p == 12 ) ) { std::cout << "SOLUTION #" << std::setw( 2 ) << sol++ << std::setw( 2 ) << ":\t" << std::setw( 2 ) << f << "\t\t " << std::setw( 3 ) << p << "\t\t" << std::setw( 6 ) << s << "\n"; } } } } return 0;
}</lang>
- Output:
FIRE POLICE SANITATION SOLUTION # 1: 1 4 7 SOLUTION # 2: 1 6 5 SOLUTION # 3: 2 4 6 SOLUTION # 4: 2 6 4 SOLUTION # 5: 3 2 7 SOLUTION # 6: 3 4 5 SOLUTION # 7: 4 2 6 SOLUTION # 8: 4 6 2 SOLUTION # 9: 5 4 3 SOLUTION #10: 5 6 1 SOLUTION #11: 6 2 4 SOLUTION #12: 6 4 2 SOLUTION #13: 7 2 3 SOLUTION #14: 7 4 1
Haskell
<lang Haskell>options :: Int -> Int -> Int -> [(Int, Int, Int)] options lo hi total =
(\ds -> filter even ds >>= \x -> filter (/= x) ds >>= \y -> [total - (x + y)] >>= \z -> case y /= z && lo <= z && z <= hi of True -> [(x, y, z)] _ -> []) [lo .. hi]
-- TEST ----------------------------------------------------------------------- main :: IO () main = do
let xs = options 1 7 12 putStrLn "(Police, Sanitation, Fire)\n" mapM_ print xs mapM_ putStrLn ["\nNumber of options: ", show (length xs)]</lang>
Reaching for a little more syntactic sugar, the options function above could also be re-written either as a list comprehension, <lang Haskell>options :: Int -> Int -> Int -> [(Int, Int, Int)] options lo hi total =
let ds = [lo .. hi] in [ (x, y, z) | x <- filter even ds , y <- filter (/= x) ds , let z = total - (x + y) , y /= z && lo <= z && z <= hi ]</lang>
or in Do notation: <lang haskell>import Control.Monad (guard)
options :: Int -> Int -> Int -> [(Int, Int, Int)] options lo hi total =
let ds = [lo .. hi] in do x <- filter even ds y <- filter (/= x) ds let z = total - (x + y) guard $ y /= z && lo <= z && z <= hi return (x, y, z)</lang>
- Output:
(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) Number of options: 14
JavaScript
ES5
<lang JavaScript>(function () {
'use strict';
// NUMBERING CONSTRAINTS --------------------------------------------------
// options :: Int -> Int -> Int -> [(Int, Int, Int)] function options(lo, hi, total) { var bind = flip(concatMap), ds = enumFromTo(lo, hi);
return bind(filter(even, ds), function (x) { // X is even, return bind(filter(function (d) { return d !== x; }, ds), function (y) { // Y is distinct from X, return bind([total - (x + y)], function (z) { // Z sums with x and y to total, and is in ds. return z !== y && lo <= z && z <= hi ? [ [x, y, z] ] : []; })})})};
// GENERIC FUNCTIONS ------------------------------------------------------
// concatMap :: (a -> [b]) -> [a] -> [b] function concatMap(f, xs) { return [].concat.apply([], xs.map(f)); };
// enumFromTo :: Int -> Int -> [Int] function enumFromTo(m, n) { return Array.from({ length: Math.floor(n - m) + 1 }, function (_, i) { return m + i; }); };
// even :: Integral a => a -> Bool function even(n) { return n % 2 === 0; };
// filter :: (a -> Bool) -> [a] -> [a] function filter(f, xs) { return xs.filter(f); };
// flip :: (a -> b -> c) -> b -> a -> c function flip(f) { return function (a, b) { return f.apply(null, [b, a]); }; };
// length :: [a] -> Int function length(xs) { return xs.length; };
// map :: (a -> b) -> [a] -> [b] function map(f, xs) { return xs.map(f); };
// show :: a -> String function show(x) { return JSON.stringify(x); }; //, null, 2);
// unlines :: [String] -> String function unlines(xs) { return xs.join('\n'); };
// TEST ------------------------------------------------------------------- var xs = options(1, 7, 12); return '(Police, Sanitation, Fire)\n\n' + unlines(map(show, xs)) + '\n\nNumber of options: ' + length(xs);
})();</lang>
- Output:
(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] Number of options: 14
ES6
By composition of generic functions.
<lang JavaScript>(() => {
'use strict';
// NUMBERING CONSTRAINTS --------------------------------------------------
// options :: Int -> Int -> Int -> [(Int, Int, Int)] const options = (lo, hi, total) => { const bind = flip(concatMap), ds = enumFromTo(lo, hi);
return bind(filter(even, ds), x => bind(filter(d => d !== x, ds), y => bind([total - (x + y)], z => (z !== y && lo <= z && z <= hi) ? [ [x, y, z] ] : [] ) ) ) };
// GENERIC FUNCTIONS ------------------------------------------------------
// concatMap :: (a -> [b]) -> [a] -> [b] const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
// enumFromTo :: Int -> Int -> [Int] const enumFromTo = (m, n) => Array.from({ length: Math.floor(n - m) + 1 }, (_, i) => m + i);
// even :: Integral a => a -> Bool const even = n => n % 2 === 0;
// filter :: (a -> Bool) -> [a] -> [a] const filter = (f, xs) => xs.filter(f);
// flip :: (a -> b -> c) -> b -> a -> c const flip = f => (a, b) => f.apply(null, [b, a]);
// length :: [a] -> Int const length = xs => xs.length;
// map :: (a -> b) -> [a] -> [b] const map = (f, xs) => xs.map(f);
// show :: a -> String const show = x => JSON.stringify(x) //, null, 2);
// unlines :: [String] -> String const unlines = xs => xs.join('\n');
// TEST ------------------------------------------------------------------- const xs = options(1, 7, 12); return '(Police, Sanitation, Fire)\n\n' + unlines(map(show, xs)) + '\n\nNumber of options: ' + length(xs);
})();</lang>
- Output:
(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] Number of options: 14
Kotlin
<lang scala>// version 1.1.2
fun main(args: Array<String>) {
println("Police Sanitation Fire") println("------ ---------- ----") var count = 0 for (i in 2..6 step 2) { for (j in 1..7) { if (j == i) continue for (k in 1..7) { if (k == i || k == j) continue if (i + j + k != 12) continue println(" $i $j $k") count++ } } } println("\n$count valid combinations")
}</lang>
- Output:
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
Lua
<lang lua> print( "Fire", "Police", "Sanitation" ) sol = 0 for f = 1, 7 do
for p = 1, 7 do for s = 1, 7 do if s + p + f == 12 and p % 2 == 0 and f ~= p and f ~= s and p ~= s then print( f, p, s ); sol = sol + 1 end end end
end print( string.format( "\n%d solutions found", sol ) ) </lang>
- Output:
Fire Police Sanitation 1 4 7 1 6 5 2 4 6 2 6 4 3 2 7 3 4 5 4 2 6 4 6 2 5 4 3 5 6 1 6 2 4 6 4 2 7 2 3 7 4 1 14 solutions found
Perl
<lang Perl>
- !/usr/bin/perl
my @even_numbers;
for (1..7) {
if ( $_ % 2 == 0) { push @even_numbers, $_; }
}
print "Police\tFire\tSanitation\n";
foreach my $police_number (@even_numbers) {
for my $fire_number (1..7) { for my $sanitation_number (1..7) { if ( $police_number + $fire_number + $sanitation_number == 12 && $police_number != $fire_number && $fire_number != $sanitation_number && $sanitation_number != $police_number) { print "$police_number\t$fire_number\t$sanitation_number\n"; } } }
} </lang>
Perl 6
<lang perl6>for (1..7).combinations(3).grep(*.sum == 12) {
for .permutations\ .grep(*.[0] %% 2) { say <police fire sanitation> Z=> .list; }
} </lang>
- Output:
(police => 4 fire => 1 sanitation => 7) (police => 4 fire => 7 sanitation => 1) (police => 6 fire => 1 sanitation => 5) (police => 6 fire => 5 sanitation => 1) (police => 2 fire => 3 sanitation => 7) (police => 2 fire => 7 sanitation => 3) (police => 2 fire => 4 sanitation => 6) (police => 2 fire => 6 sanitation => 4) (police => 4 fire => 2 sanitation => 6) (police => 4 fire => 6 sanitation => 2) (police => 6 fire => 2 sanitation => 4) (police => 6 fire => 4 sanitation => 2) (police => 4 fire => 3 sanitation => 5) (police => 4 fire => 5 sanitation => 3)
REXX
A little extra code was added to allow the specification for the high department number as well as the sum.
Also, extra code was added to nicely format a title (header) for the output, as well as displaying the number of solutions found. <lang rexx>/*REXX program finds/displays all possible variants of (3) department numbering puzzle.*/ parse arg high sum . /*obtain optional arguments from the CL*/ if high== | high=="," then high= 7 /*Not specified? Then use the default.*/ if sum== | sum=="," then sum=12 /* " " " " " " */ @pd= ' police '; @fd= " fire " ; @sd= ' sanitation ' /*define names of departments.*/ @dept= ' department '; L=length(@dept) /*literal; and also its length*/
- =0 /*initialize the number of solutions. */
do PD=2 by 2 to high /*try numbers for the police department*/ do FD=1 for high /* " " " " fire " */ if FD==PD then iterate /*Same FD# & PD#? They must be unique.*/ if FD+PD>sum-1 then iterate PD /*Is sum too large? Try another PD#. */ do SD=1 for high /*try numbers for the sanitation dept. */ if SD==PD | SD==FD then iterate /*Is SD# ¬unique? They must be unique,*/ $=PD+FD+SD /*compute sum of department numbers. */ if $> sum then iterate FD /*Is the sum too high? Try another FD#*/ if $\==sum then iterate /*Is the sum ¬correct? " " SD#*/ #=# + 1 /*bump the number of solutions (so far)*/ if #==1 then do /*Is this the 1st solution? Show hdr.*/ say center(@pd, L) center(@fd, L) center(@sd, L) say copies(center( @dept, L)' ', 3) say copies(center('number', L)' ', 3) say center(, L, "═") center(, L, "═") center(, L, "═") end say center(PD, L) center(FD, L) center(SD, L) /*display a solution.*/ end /*SD*/ end /*FD*/ end /*PD*/
say /*display a blank line before the #sols*/ if #==0 then #= 'no' /*use a better word for bupkis. */ say # "solutions found." /*stick a fork in it, we're all done. */</lang>
- output when using the default inputs:
police fire sanitation department department department number number number ════════════ ════════════ ════════════ 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 solutions found.
zkl
<lang zkl>Utils.Helpers.pickNFrom(3,[1..7].walk()) // 35 combos .filter(fcn(numbers){ numbers.sum(0)==12 }) // which all sum to 12 (==5) .println();</lang>
- Output:
L(L(1,4,7),L(1,5,6),L(2,3,7),L(2,4,6),L(3,4,5))
Note: The sum of three odd numbers is odd, so a+b+c=12 means at least one even nmber (1 even, two odd or 3 even). Futher, 2a+b=12, a,b in (2,4,6) has one solution: a=2,b=4
For a table with repeated solutions using nested loops: <lang zkl>println("Police Fire Sanitation"); foreach p,f,s in ([2..7,2], [1..7], [1..7])
{ if((p!=s!=f) and p+f+s==12) println(p,"\t",f,"\t",s) }</lang>
- Output:
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