Department numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|AppleScript}}: (added output for the simpler version))
Line 43: Line 43:
end script
end script
concatMap(result, {12 - (x + y)})
concatMap(result, {12 - (x + y)}) --Z
end |λ|
end |λ|
end script
end script
concatMap(result, {1, 2, 3, 4, 5, 6, 7})
concatMap(result, {1, 2, 3, 4, 5, 6, 7}) --Y
end |λ|
end |λ|
end script
end script
unlines(concatMap(result, {2, 4, 6}))
unlines(concatMap(result, {2, 4, 6})) --X
end run
end run



Revision as of 16:13, 25 May 2017

Task
Department numbers
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

Briefly, composing a solution from generic functions:

<lang AppleScript>on run

   script
       on |λ|(x)
           script
               on |λ|(y)
                   script
                       on |λ|(z)
                           if y ≠ z and 1 ≤ z and z ≤ 7 then
                               {{x, y, z} as string}
                           else
                               {}
                           end if
                       end |λ|
                   end script
                   
                   concatMap(result, {12 - (x + y)}) --Z
               end |λ|
           end script
           
           concatMap(result, {1, 2, 3, 4, 5, 6, 7}) --Y
       end |λ|
   end script
   
   unlines(concatMap(result, {2, 4, 6})) --X

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

-- 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

-- 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

-- unlines :: [String] -> String on unlines(xs)

   intercalate(linefeed, xs)

end unlines</lang>

Output:
237
246
264
273
417
426
435
453
462
471
615
624
642
651

Or more generally:

Translation of: JavaScript
Translation of: Haskell

<lang AppleScript>-- NUMBERING CONSTRAINTS ------------------------------------------------------

-- options :: Int -> Int -> Int -> [(Int, Int, Int)] on options(lo, hi, total)

   set ds to enumFromTo(lo, hi)
   
   script Xeven
       on |λ|(x)
           script Ydistinct
               on |λ|(y)
                   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)}) -- Z IS IN RANGE
               end |λ|
           end script
           
           script notX
               on |λ|(d)
                   d ≠ x
               end |λ|
           end script
           
           concatMap(Ydistinct, filter(notX, ds)) -- Y IS NOT X
       end |λ|
   end script
   
   concatMap(Xeven, filter(my even, ds)) -- X IS 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>

  1. include <iostream>
  2. 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

Bare minimum: <lang haskell>main :: IO () main =

 mapM_ print $
 [2, 4, 6] >>=
 \x ->
    [1 .. 7] >>=
    \y ->
       [12 - (x + y)] >>=
       \z ->
          if y /= z && 1 <= z && z <= 7
            then [(x, y, z)]
            else []</lang>

or, resugaring this into list comprehension format: <lang Haskell>main :: IO () main =

 mapM_
   print
   [ (x, y, z)
   | x <- [2, 4, 6] 
   , y <- [1 .. 7] 
   , z <- [12 - (x + y)] 
   , y /= z && 1 <= z && z <= 7 ]</lang>
Output:
(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)

Or, more generally: <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 again 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

Briefly: <lang JavaScript>(function () {

   'use strict';
   // concatMap :: (a -> [b]) -> [a] -> [b]
   function concatMap(f, xs) {
       return [].concat.apply([], xs.map(f));
   };
   return '(Police, Sanitation, Fire)\n' +
       concatMap(function (x) {
           return concatMap(function (y) {
               return concatMap(function (z) {
                   return z !== y && 1 <= z && z <= 7 ? [
                       [x, y, z]
                   ] : [];
               }, [12 - (x + y)]);
           }, [1, 2, 3, 4, 5, 6, 7]);
       }, [2, 4, 6])
       .map(JSON.stringify)
       .join('\n');

})();</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]

Or, more generally:

Translation of: Haskell

<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

Briefly: <lang JavaScript>(() => {

   // concatMap :: (a -> [b]) -> [a] -> [b]
   const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
   return '(Police, Sanitation, Fire)\n' +
       concatMap(x =>
           concatMap(y =>
               concatMap(z =>
                   z !== y && 1 <= z && z <= 7 ? [
                       [x, y, z]
                   ] : [], [12 - (x + y)]
               ), [1, 2, 3, 4, 5, 6, 7]
           ), [2, 4, 6]
       )
       .map(JSON.stringify)
       .join('\n');

})();</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]

Or, more generally, by composition of generic functions:

Translation of: Haskell

<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>

  1. !/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.

Two optimizing statements were added (for speed),   but for this simple puzzle they aren't needed.

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*/

  1. =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#. */    /* ◄■■■■■■ optimizing code*/
         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#*/    /* ◄■■■■■■ optimizing code*/
         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.

Scala

<lang scala>val depts = {

 (1 to 7).permutations.map{ n => (n(0),n(1),n(2)) }.toList.distinct  // All permutations of possible department numbers
 .filter{ n => n._1 % 2 == 0 }                                       // Keep only even numbers favored by Police Chief
 .filter{ n => n._1 + n._2 + n._3 == 12 }                            // Keep only numbers that add to 12

}

{ println( "(Police, Sanitation, Fire)") println( depts.mkString("\n") ) } </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)

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