Department numbers

From Rosetta Code
(Redirected from Department Numbers)
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   12.

The Chief of the Police doesn't like odd numbers and wants to have an even number for his department.


Task

Write a computer program which outputs all valid combinations.


Possible output   (for the 1st and 14th solutions):

 --police--  --sanitation--  --fire-- 
     2             3            7 
     6             5            1



11l

Translation of: C
print(‘Police     Sanitation         Fire’)
print(‘----------------------------------’)

L(police) (2..6).step(2)
   L(sanitation) 1..7
      L(fire) 1..7
         I police!=sanitation & sanitation!=fire & fire!=police & police+fire+sanitation==12
            print(police"\t\t"sanitation"\t\t"fire)
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

8080 Assembly

	org	100h
	lxi	h,obuf	; HL = output buffer
	mvi	b,2	; B = police
pol:	mvi	c,1	; C = sanitation
san:	mvi	d,1	; D = fire
fire:	mov	a,b	; Fire equal to police?
	cmp	d
	jz	next	; If so, invalid combination
	mov	a,c	; Fire equal to sanitation?
	cmp	d
	jz	next	; If so, invalid combination
	mov	a,b	; Total equal to 12?
	add	c
	add	d
	cpi	12
	jnz	next	; If not, invalid combination	
	mov	a,b	; Combination is valid, add to output
	call	num
	mov	a,c
	call 	num
	mov	a,d
	call	num
	mvi	m,13	; Add a newline to the output
	inx	h
	mvi	m,10
	inx	h
next:	mvi	a,7	; Load 7 to compare to
	inr	d	; Next fire number
	cmp	d	; Reached the end?
	jnc	fire	; If not, next fire number
	inr	c	; Otherwise, next sanitation number
	cmp	c	; Reached the end?
	jnc	san	; If not, next sanitation number
	inr	b	; Increment police number twice
	inr	b	; (twice, because it must be even)
	cmp	b	; Reached the end?
	jnc	pol 	; If not, next police number
	mvi	m,'$'	; If so, we're done - add CP/M string terminator
	mvi	c,9	; Print the output string
	lxi	d,ohdr
	jmp	5
num:	adi	'0'	; Add number A and space to the output
	mov	m,a
	inx	h
	mvi	m,' '
	inx	h
	ret
ohdr:	db	'P S F',13,10
obuf:	equ	$	; Output buffer goes after program
Output:
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

8086 Assembly

	cpu	8086
	bits	16
	org	100h
section	.text
	mov	di,obuf		; Output buffer
	mov	bl,2		; BL = police
pol:	mov	cl,1		; CL = sanitation
san:	mov	dl,1		; DL = fire
fire:	cmp	bl,cl		; Police equal to sanitation?
	je	next		; Invalid combination
	cmp	bl,dl		; Police equal to fire?
	je	next		; Invalid combination
	cmp	cl,dl		; Sanitation equal to fire?
	je	next		; Invalid combination
	mov	al,bl		; Total equal to 12?
	add	al,cl
	add	al,dl
	cmp	al,12
	jne	next		; If not, invalid combination
	mov	al,bl		; Combination is valid, write the three numbers
	call	num 
	mov	al,cl
	call 	num
	mov	al,dl
	call 	num
	mov	ax,0A0Dh	; And a newline
	stosw
next:	mov	al,7		; Load 7 to compare to
	inc	dx		; Increment fire number
	cmp	al,dl		; If 7 or less,
	jae	fire		; next fire number.
	inc	cx		; Otherwise, ncrement sanitation number
	cmp	al,cl		; If 7 or less,
	jae	san		; next sanitation number
	inc	bx		; Increment police number twice
	inc	bx		; (it must be even)
	cmp	al,bl		; If 7 or less,
	jae	pol		; next police number.
	mov	byte [di],'$'	; At the end, terminate the string
	mov	dx,ohdr		; Tell MS-DOS to print it
	mov	ah,9
	int	21h
	ret
num:	mov	ah,' '		; Space 
	add	al,'0'		; Add number to output
	stosw			; Store number and space
	ret
section	.data
ohdr:	db	'P S F',13,10	; Header
obuf:	equ	$		; Place to write output
Output:
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


Action!

PROC Main()
  BYTE p,s,f

  PrintE("P S F")
  FOR p=2 TO 6 STEP 2
  DO
    FOR s=1 TO 7
    DO
      FOR f=1 TO 7
      DO
        IF p#s AND p#f AND s#f AND p+s+f=12 THEN
          PrintF("%B %B %B%E",p,s,f)
        FI
      OD
    OD
  OD
RETURN
Output:

Screenshot from Atari 8-bit computer

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

Ada

with Ada.Text_IO;

procedure Department_Numbers is
   use Ada.Text_IO;
begin
   Put_Line (" P S F");
   for Police in 2 .. 6 loop
      for Sanitation in 1 .. 7 loop
         for Fire in 1 .. 7 loop
            if
              Police mod 2 = 0                and
              Police + Sanitation + Fire = 12 and
              Sanitation /= Police            and
              Sanitation /= Fire              and
              Police     /= Fire
            then
               Put_Line (Police'Image & Sanitation'Image & Fire'Image);
            end if;
         end loop;
      end loop;
   end loop;
end Department_Numbers;
Output:
 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

Aime

integer p, s, f;

p = 0;
while ((p += 2) <= 7) {
    s = 0;
    while ((s += 1) <= 7) {
        f = 0;
        while ((f += 1) <= 7) {
            if (p + s + f == 12 && p != s && p != f && s != f) {
                o_form(" ~ ~ ~\n", p, s, f);
            }
        }
    }
}

ALGOL 68

As noted in the Fortran sample, once the police and sanitation departments are posited, the fire department value is fixed

BEGIN
    # show possible department number allocations for police, sanitation and fire departments #
    # the police department number must be even, all department numbers in the range 1 .. 7   #
    # the sum of the department numbers must be 12                                            #
    INT max department number =  7;
    INT department sum        = 12;
    print( ( "police sanitation fire", newline ) );
    FOR police FROM 2 BY 2 TO max department number DO
        FOR sanitation TO max department number DO
            IF sanitation /= police THEN
                INT fire = ( department sum - police ) - sanitation;
                IF  fire > 0 AND fire <= max department number
                AND fire /= sanitation
                AND fire /= police
                THEN
                    print( ( whole( police,      -6 )
                           , whole( sanitation, -11 )
                           , whole( fire,        -5 )
                           , newline
                           )
                         )
                FI
            FI
        OD
    OD
END
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

ALGOL W

Translation of: ALGOL 68
begin
    % show possible department number allocations for police, sanitation and fire departments %
    % the police department number must be even, all department numbers in the range 1 .. 7   %
    % the sum of the department numbers must be 12                                            %
    integer MAX_DEPARTMENT_NUMBER, DEPARTMENT_SUM;
    MAX_DEPARTMENT_NUMBER :=  7;
    DEPARTMENT_SUM        := 12;
    write( "police sanitation fire" );
    for police := 2 step 2  until MAX_DEPARTMENT_NUMBER do begin
        for sanitation := 1 until MAX_DEPARTMENT_NUMBER do begin
            IF sanitation not = police then begin
                integer fire;
                fire := ( DEPARTMENT_SUM - police ) - sanitation;
                if  fire > 0 and fire <= MAX_DEPARTMENT_NUMBER and fire not = sanitation and fire not = police then begin
                    write( s_w := 0, i_w := 6, police, i_w := 11, sanitation, i_w := 5, fire )
                end if_valid_combination
            end if_sanitation_ne_police
        end for_sanitation
    end for_police
end.
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

APL

'PSF'((⌿⍨)((∪≡⊢)¨↓∧(0=2|1[2])12=+/))↑,⍳3/7

This prints each triplet of numbers from 1 to 7 for which:

  1. the elements are unique: (∪≡⊢)¨↓
  2. the first element is even: (0=2|1⌷[2]⊢)
  3. the sum of the elements is 12: 12=+/
Output:
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


AppleScript

Briefly, composing a solution from generic functions:

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
Output:
237
246
264
273
417
426
435
453
462
471
615
624
642
651

Or more generally:

Translation of: JavaScript
Translation of: Haskell
-- 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
                                {{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
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

Arturo

loop 1..7 'x [
    loop 1..7 'y [
        loop 1..7 'z [
            if all? @[
                even? x
                12 = sum @[x y z]
                3 = size unique @[x y z]
            ] -> print [x y z]
        ]
    ]
]
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

Asymptote

write("--police--  --sanitation--  --fire--");
 
for(int police = 2; police < 6; police += 2) {
  for(int sanitation = 1; sanitation < 7; ++sanitation) {
    for(int fire = 1; fire < 7; ++fire) {
      if(police != sanitation && sanitation != fire && fire != police && police+fire+sanitation == 12){
        write("    ", police, suffix=none);
        write("             ", sanitation, suffix=none);
        write("            ", fire);
      }
    }
  }
}

AutoHotkey

perm(elements, n, opt:="", Delim:="", str:="", res:="", j:=0, dup:="") {	
	res := IsObject(res) ? res : [], dup := IsObject(dup) ? dup : []
	if (n > j) 
		Loop, parse, elements, % Delim
			res := !(InStr(str, A_LoopField) && !(InStr(opt, "rep"))) ? perm(elements, n, opt, Delim, trim(str Delim A_LoopField, Delim), res, j+1, dup) : res
	else if !(dup[x := perm_sort(str, Delim)] && (InStr(opt, "comb")))
		dup[x] := 1, res.Insert(str)
	return res, j++
}

perm_sort(str, Delim){
	Loop, Parse, str, % Delim
		res .= A_LoopField "`n"
	Sort, res, D`n
	return StrReplace(res, "`n", Delim)
}
Example:
elements := "1234567", n := 3
for k, v in perm(elements, n)
	if (SubStr(v, 1, 1) + SubStr(v, 2, 1) + SubStr(v, 3, 1) = 12) && (SubStr(v, 1, 1) / 2 = Floor(SubStr(v, 1, 1)/2))
		res4 .= v "`n"

MsgBox, 262144, , % res4
return
Outputs:
237
246
264
273
417
426
435
453
462
471
615
624
642
651

AWK

# syntax: GAWK -f DEPARTMENT_NUMBERS.AWK
BEGIN {
    print(" # FD PD SD")
    for (fire=1; fire<=7; fire++) {
      for (police=1; police<=7; police++) {
        for (sanitation=1; sanitation<=7; sanitation++) {
          if (rules() ~ /^1+$/) {
            printf("%2d %2d %2d %2d\n",++count,fire,police,sanitation)
          }
        }
      }
    }
    exit(0)
}
function rules(  stmt1,stmt2,stmt3) {
    stmt1 = fire != police && fire != sanitation && police != sanitation
    stmt2 = fire + police + sanitation == 12
    stmt3 = police % 2 == 0
    return(stmt1 stmt2 stmt3)
}
Output:
 # FD PD SD
 1  1  4  7
 2  1  6  5
 3  2  4  6
 4  2  6  4
 5  3  2  7
 6  3  4  5
 7  4  2  6
 8  4  6  2
 9  5  4  3
10  5  6  1
11  6  2  4
12  6  4  2
13  7  2  3
14  7  4  1

BCPL

get "libhdr"

let start() be
    for p=2 to 6 by 2
        for s=1 to 7
            for f=1 to 7
                if p~=s & s~=f & p~=f & p+s+f=12 then
                    writef("%N %N %N*N", p, s, f)
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

BASIC

Applesoft BASIC

The Sinclair ZX81 BASIC solution works without any changes.

BASIC256

print "--police--  --sanitation--  --fire--"

for police = 2 to 7 step 2
    for fire = 1 to 7
        if fire = police then continue for
        sanitation = 12 - police - fire
        if sanitation = fire or sanitation = police then continue for
        if sanitation >= 1 and sanitation <= 7 then
            print rjust(police, 6); rjust(fire, 13); rjust(sanitation, 12)
        end if
    next fire
next police
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

Chipmunk Basic

Works with: Chipmunk Basic version 3.6.4
10 CLS
20 PRINT "--police--  --sanitation--  --fire--"
30 FOR police = 2 TO 7 STEP 2
40    FOR fire = 1 TO 7
50        sanitation = 12-police-fire
60        IF sanitation >= 1 AND sanitation <= 7 THEN
70            PRINT TAB (5)police TAB (18)fire TAB (30)sanitation
80        endif
90    NEXT fire
100 NEXT police
Output:
Same as FreeBASIC entry.

Craft Basic

print "P S F"

for p = 2 to 7 step 2

	for s = 1 to 7

		if s <> p then

			let f = (12 - p) - s

			if f > 0 and f <= 7 and f <> s and f <> p then

				print  p, " ", s, " ", f

			endif

		endif

	next s

next p

end
Output:
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

Run BASIC

print "police fire sanitation"

for police = 2 to 7 step 2
    for fire = 1 to 7
        if fire = police then [cont]
        sanitation = (12-police)-fire
        if sanitation <= 0 or sanitation > 7 or sanitation = fire or sanitation = police then [cont]
    print "  "; police; chr$(9); fire; chr$(9); sanitation
[cont]
    next fire
next police

PureBasic

OpenConsole()
PrintN("--police--  --sanitation--  --fire--")

For police = 2 To 7 Step 2
  For fire = 1 To 7
    If fire = police:
      Continue
    EndIf
    sanitation = 12 - police - fire
    If sanitation = fire Or sanitation = police: Continue : EndIf
    If sanitation >= 1 And sanitation <= 7:
      PrintN("    " + Str(police) + #TAB$ + #TAB$ + Str(fire) + #TAB$ + #TAB$ + Str(sanitation))
    EndIf
  Next fire
Next police

Input()
CloseConsole()
Output:
Same as BASIC256 entry.

Yabasic

print "--police--  --sanitation--  --fire--"

for police = 2 to 7 step 2
    for fire = 1 to 7
        if fire = police  continue
        sanitation = 12 - police - fire
        if sanitation = fire or sanitation = police  continue
        if sanitation >= 1 and sanitation <= 7  print police using "######", fire using "############", sanitation using "###########"
    next fire
next police
Output:
Same as BASIC256 entry.


IS-BASIC

100 PRINT "Police","San.","Fire"
110 FOR P=2 TO 7 STEP 2
120   FOR S=1 TO 7
130     IF S<>P THEN
131       LET F=(12-P)-S
140       IF F>0 AND F<=7 AND F<>S AND F<>P THEN PRINT P,S,F
141     END IF
150   NEXT
160 NEXT

Minimal BASIC

Translation of: Sinclair ZX81 BASIC
10 REM Department numbers
20 PRINT "POLICE SANITATION FIRE"
30 FOR P = 2 TO 7 STEP 2
40 FOR S = 1 TO 7
50 IF S = P THEN 120
60 LET F = (12-P)-S
70 IF F <= 0 THEN 120
80 IF F > 7 THEN 120
90 IF F = S THEN 120
100 IF F = P THEN 120
110 PRINT TAB(3); P; TAB(11); S; TAB(19); F
120 NEXT S
130 NEXT P
140 END

Quite BASIC

Translation of: Sinclair ZX81 BASIC
10 REM Department numbers
20 PRINT "POLICE SANITATION FIRE"
30 FOR P = 2 TO 7 STEP 2
40 FOR S = 1 TO 7
50 IF S = P THEN 80
60 LET F = (12-P)-S
70 IF F > 0 AND F <= 7 AND F <> S AND F <> P THEN PRINT "   ";P;"       ";S;"       ";F
80 NEXT S
90 NEXT P
100 END
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

Sinclair ZX81 BASIC

Works with 1k of RAM. This program ought not to need more than minimal changes to be compatible with any old-style BASIC dialect.

10 PRINT "POLICE SANITATION FIRE"
20 FOR P=2 TO 7 STEP 2
30 FOR S=1 TO 7
40 IF S=P THEN NEXT S
50 LET F=(12-P)-S
60 IF F>0 AND F<=7 AND F<>S AND F<>P THEN PRINT "   ";P;"       ";S;"       ";F
70 NEXT S
80 NEXT P
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

BBC BASIC

Translation of: ALGOL 68
REM >deptnums
max_dept_num% = 7
dept_sum% = 12
PRINT "police sanitation fire"
FOR police% = 2 TO max_dept_num% STEP 2
  FOR sanitation% = 1 TO max_dept_num%
    IF sanitation% <> police% THEN
      fire% = (dept_sum% - police%) - sanitation%
      IF fire% > 0 AND fire% <= max_dept_num% AND fire% <> sanitation% AND fire% <> police% THEN PRINT "   "; police%; "       "; sanitation%; "       "; fire%
    ENDIF
  NEXT
NEXT
END
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

QBasic

PRINT "--police--  --sanitation--  --fire--"

FOR police = 2 TO 7 STEP 2
    FOR fire = 1 TO 7
        IF fire = police THEN GOTO cont
    sanitation = 12 - police - fire
    IF sanitation = fire OR sanitation = police THEN GOTO cont
    IF sanitation >= 1 AND sanitation <= 7 THEN
        PRINT USING "    #             #            #"; police; fire; sanitation
    END IF
cont:
    NEXT fire
NEXT police

XBasic

Works with: Windows XBasic
PROGRAM	"Depar/num"

DECLARE FUNCTION  Entry ()

FUNCTION  Entry ()
  PRINT "police  sanitation  fire"

  FOR police = 2 TO 7 STEP 2
    FOR fire = 1 TO 7
      IF fire = police THEN GOTO cont
      sanitation = 12 - police - fire
      IF sanitation = fire OR sanitation = police THEN GOTO cont
      IF sanitation >= 1 AND sanitation <= 7 THEN
          PRINT TAB(3); police; TAB(13); fire; TAB(22); sanitation
      END IF
cont:
    NEXT fire
  NEXT police
END FUNCTION
END PROGRAM

C

Weird that such a simple task was still not implemented in C, would be great to see some really creative ( obfuscated ) solutions for this one.

#include<stdio.h>

int main()
{
	int police,sanitation,fire;
	
	printf("Police     Sanitation         Fire\n");
	printf("----------------------------------");
	
	for(police=2;police<=6;police+=2){
		for(sanitation=1;sanitation<=7;sanitation++){
			for(fire=1;fire<=7;fire++){
				if(police!=sanitation && sanitation!=fire && fire!=police && police+fire+sanitation==12){
					printf("\n%d\t\t%d\t\t%d",police,sanitation,fire);
				}
			}
		}
	}
	
	return 0;
}

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

C#

using System;
public class Program
{
    public static void Main() {
        for (int p = 2; p <= 7; p+=2) {
            for (int s = 1; s <= 7; s++) {
                int f = 12 - p - s;
                if (s >= f) break;
                if (f > 7) continue;
                if (s == p || f == p) continue; //not even necessary
                Console.WriteLine($"Police:{p}, Sanitation:{s}, Fire:{f}");
                Console.WriteLine($"Police:{p}, Sanitation:{f}, Fire:{s}");
            }
        }
    }
}
Output:
Police:2, Sanitation:3, Fire:7
Police:2, Sanitation:7, Fire:3
Police:2, Sanitation:4, Fire:6
Police:2, Sanitation:6, Fire:4
Police:4, Sanitation:1, Fire:7
Police:4, Sanitation:7, Fire:1
Police:4, Sanitation:2, Fire:6
Police:4, Sanitation:6, Fire:2
Police:4, Sanitation:3, Fire:5
Police:4, Sanitation:5, Fire:3
Police:6, Sanitation:1, Fire:5
Police:6, Sanitation:5, Fire:1
Police:6, Sanitation:2, Fire:4
Police:6, Sanitation:4, Fire:2

C++

#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;
}
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

Clojure

(let [n (range 1 8)]
  (for [police n
        sanitation n
        fire n
        :when (distinct? police sanitation fire)
        :when (even? police)
        :when (= 12 (+ police sanitation fire))]
    (println police sanitation fire)))
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

CLU

start_up = proc ()
    po: stream := stream$primary_output()
    
    stream$putl(po, "P S F\n- - -")
    for police: int in int$from_to_by(2,7,2) do
        for sanitation: int in int$from_to(1,7) do
            for fire: int in int$from_to(1,7) do 
                if police~=sanitation 
                 & sanitation~=fire 
                 & police~=fire 
                 & police+sanitation+fire = 12
                then
                    stream$putl(po, int$unparse(police) || " " ||
                                    int$unparse(sanitation) || " " ||
                                    int$unparse(fire))
                end
            end
        end
    end
end start_up
Output:
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

COBOL

       IDENTIFICATION DIVISION.
       PROGRAM-ID. DEPARTMENT-NUMBERS.

       DATA DIVISION.
       WORKING-STORAGE SECTION.       
       01 BANNER        PIC X(24) VALUE "POLICE  SANITATION  FIRE".
       01 COMBINATION.
          03 FILLER     PIC X(5)  VALUE SPACES.
          03 POLICE     PIC 9.
          03 FILLER     PIC X(11) VALUE SPACES.
          03 SANITATION PIC 9.
          03 FILLER     PIC X(5)  VALUE SPACES.
          03 FIRE       PIC 9.
       01 TOTAL         PIC 99.

       PROCEDURE DIVISION.
       BEGIN. 
           DISPLAY BANNER.
           PERFORM POLICE-LOOP VARYING POLICE FROM 2 BY 2
           UNTIL POLICE IS GREATER THAN 6.
           STOP RUN.
 
       POLICE-LOOP. 
           PERFORM SANITATION-LOOP VARYING SANITATION FROM 1 BY 1
           UNTIL SANITATION IS GREATER THAN 7.
  
       SANITATION-LOOP.
           PERFORM FIRE-LOOP VARYING FIRE FROM 1 BY 1
           UNTIL FIRE IS GREATER THAN 7.
 
       FIRE-LOOP.
           ADD POLICE, SANITATION, FIRE GIVING TOTAL.
           IF POLICE IS NOT EQUAL TO SANITATION
               AND POLICE IS NOT EQUAL TO FIRE
               AND SANITATION IS NOT EQUAL TO FIRE
               AND TOTAL IS EQUAL TO 12,
               DISPLAY COMBINATION.
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

Cowgol

include "cowgol.coh";

typedef Dpt is int(1, 7);

# print combination if valid
sub print_comb(p: Dpt, s: Dpt, f: Dpt) is
    var out: uint8[] := {'*',' ','*',' ','*','\n',0};
    out[0] := p + '0';
    out[2] := s + '0';
    out[4] := f + '0';
    if p != s and p != f and f != s and p+s+f == 12 then
        print(&out[0]);
    end if;
end sub;

print("P S F\n"); # header

var pol: Dpt := 2;
while pol <= 7 loop
    var san: Dpt := 1;
    while san <= 7 loop
        var fire: Dpt := 1;
        while fire <= 7 loop
            print_comb(pol, san, fire);
            fire := fire + 1;
        end loop;
        san := san + 1;
    end loop;
    pol := pol + 2;
end loop;
Output:
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

D

Translation of: C++
import std.stdio, std.range;

void main() {
    int sol = 1;
    writeln("\t\tFIRE\t\tPOLICE\t\tSANITATION");
    foreach( f; iota(1,8) ) {
        foreach( p; iota(1,8) ) {
            foreach( s; iota(1,8) ) {
                if( f != p && f != s && p != s && !( p & 1 ) && ( f + s + p == 12 ) ) {
                    writefln("SOLUTION #%2d:\t%2d\t\t%3d\t\t%6d", sol++, f, p, s);
                }
            }
        }
    }
}

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  

Delphi

Translation of: Go
program Department_numbers;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  i, j, k, count: Integer;

begin
  writeln('Police  Sanitation  Fire');
  writeln('------  ----------  ----');
  count := 0;
  i := 2;
  while i < 7 do
  begin
    for j := 1 to 7 do
    begin
      if j = i then
        Continue;
      for k := 1 to 7 do
      begin
        if (k = i) or (k = j) then
          Continue;
        if i + j + k <> 12 then
          Continue;
        writeln(format('  %d         %d         %d', [i, j, k]));
        inc(count);
      end;
    end;
    inc(i, 2);
  end;
  writeln(#10, count, ' valid combinations');
  readln;
end.

Draco

proc main() void:
    byte police, sanitation, fire;

    writeln("Police  Sanitation  Fire");
    for police from 2 by 2 upto 7 do
        for sanitation from 1 upto 7 do
            for fire from 1 upto 7 do
                if  police /= sanitation 
                and police /= fire 
                and sanitation /= fire
                and police + sanitation + fire = 12 then
                    writeln(police:6, "  ", sanitation:10, "  ", fire:4)
                fi
            od
        od
    od
corp
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

EasyLang

Translation of: C
numfmt 0 3
for pol = 2 step 2 to 6
   for san = 1 to 7
      for fire = 1 to 7
         if pol <> san and san <> fire and fire <> pol
            if pol + fire + san = 12
               print pol & san & fire
            .
         .
      .
   .
.

Elixir

IO.puts("P - F - S")
for p <- [2,4,6],
  f <- 1..7,
  s <- 1..7,
  p != f and p != s and f != s and p + f + s == 12 do
    "#{p} - #{f} - #{s}"
  end
  |> Enum.each(&IO.puts/1)
P - F - S
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

Excel

LAMBDA

Binding the name departmentNumbers to the following expression in the Name Manager of the Excel WorkBook:

(See LAMBDA: The ultimate Excel worksheet function)

departmentNumbers
=validRows(
    LAMBDA(ab, 
        LET(
            x, INDEX(ab, 0, 1),
            y, INDEX(ab, 0, 2),
            z, 12 - (x + y),
            
            IF(y <> z,
                IF(1 <= z,
                    IF(7 >= z,
                        CHOOSE({1, 2, 3}, x, y, z),
                        NA()
                    ),
                    NA()
                ),
                NA()
            )
        )
    )(
        cartesianProduct({2;4;6})(
            SEQUENCE(7, 1, 1, 1)
        ) 
    )
)

and also assuming the following generic bindings in the Name Manager for the WorkBook:

cartesianProduct
=LAMBDA(xs,
    LAMBDA(ys,
        LET(
            ny, ROWS(ys),
            ixs, SEQUENCE(ROWS(xs) * ny, 2, 1, 1),

            IF(0 <> MOD(ixs, 2),
                INDEX(xs,
                    1 + QUOTIENT(ixs, ny * 2)
                ),
                LET(
                    r, MOD(QUOTIENT(ixs, 2), ny),

                    INDEX(ys, IF(0 = r, ny, r))
                )
            )
        )
    )
)


validRows
=LAMBDA(xs,
    LET(
        ixs, SEQUENCE(ROWS(xs), 1, 1, 1),
        valids, FILTER(
            ixs,
            LAMBDA(i,
                NOT(ISNA(INDEX(xs, i)))
            )(ixs)
        ),

        INDEX(
            xs,
            valids,
            SEQUENCE(
                1,
                COLUMNS(xs)
            )
        )
    )
)
Output:

The formula in cell B2 below defines a two-dimensional array which populates the range B2:D15:

fx =departmentNumbers
A B C D
1 Valid department numbers
2 2 3 7
3 2 4 6
4 2 6 4
5 2 7 3
6 4 1 7
7 4 2 6
8 4 3 5
9 4 5 3
10 4 6 2
11 4 7 1
12 6 1 5
13 6 2 4
14 6 4 2
15 6 5 1

F#

// A function to generate department numbers. Nigel Galloway: May 2nd., 2018
type dNum = {Police:int; Fire:int; Sanitation:int}
let fN n=n.Police%2=0&&n.Police+n.Fire+n.Sanitation=12&&n.Police<>n.Fire&&n.Police<>n.Sanitation&&n.Fire<>n.Sanitation
List.init (7*7*7) (fun n->{Police=n%7+1;Fire=(n/7)%7+1;Sanitation=(n/49)+1})|>List.filter fN|>List.iter(printfn "%A")
Output:
{Police = 6;
 Fire = 5;
 Sanitation = 1;}
{Police = 4;
 Fire = 7;
 Sanitation = 1;}
{Police = 6;
 Fire = 4;
 Sanitation = 2;}
{Police = 4;
 Fire = 6;
 Sanitation = 2;}
{Police = 4;
 Fire = 5;
 Sanitation = 3;}
{Police = 2;
 Fire = 7;
 Sanitation = 3;}
{Police = 6;
 Fire = 2;
 Sanitation = 4;}
{Police = 2;
 Fire = 6;
 Sanitation = 4;}
{Police = 6;
 Fire = 1;
 Sanitation = 5;}
{Police = 4;
 Fire = 3;
 Sanitation = 5;}
{Police = 4;
 Fire = 2;
 Sanitation = 6;}
{Police = 2;
 Fire = 4;
 Sanitation = 6;}
{Police = 4;
 Fire = 1;
 Sanitation = 7;}
{Police = 2;
 Fire = 3;
 Sanitation = 7;}

Factor

USING: formatting io kernel math math.combinatorics math.ranges
sequences sets ;
IN: rosetta-code.department-numbers

7 [1,b] 3 <k-permutations>
[ [ first even? ] [ sum 12 = ] bi and ] filter

"{ Police, Sanitation, Fire }" print nl
[ "%[%d, %]\n" printf ] each
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 }

Fermat

!!'Police Sanitation Fire';
!!'------|----------|----';
for p = 2 to 6 by 2 do
    for s = 1 to 7 do
        for f = 1 to 7 do
            if p+f+s=12 and f<>p and f<>s and s<>p then !!(' ',p,'       ',s,'      ',f);
    fi od od od;
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

FOCAL

01.10 F P=2,2,6;F S=1,7;F G=1,7;D 2
01.20 Q

02.10 I (P-S)2.2,2.6,2.2
02.20 I (P-G)2.3,2.6,2.3
02.30 I (S-G)2.4,2.6,2.4
02.40 I (P+S+G-12)2.6,2.5,2.6
02.50 T %1,P,S,G,!
02.60 R
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

Forth

\ if department numbers are valid, print them on a single line
: fire ( pol san fir -- )
    2dup = if 2drop drop exit then
    2 pick over = if 2drop drop exit then
    rot . swap . . cr ;

\ tries to assign numbers with given policeno and sanitationno
\ and fire = 12 - policeno - sanitationno
: sanitation ( pol san -- )
    2dup = if 2drop exit then             \ no repeated numbers
    12 over - 2 pick -                    \ calculate fireno
    dup 1 < if 2drop drop exit then       \ cannot be less than 1
    dup 7 > if 2drop drop exit then       \ cannot be more than 7
    fire ;

\ tries to assign numbers with given policeno
\ and sanitation = 1, 2, 3, ..., or 7
: police ( pol -- )
    8 1 do dup i sanitation loop drop ;

\ tries to assign numbers with police = 2, 4, or 6
: departments cr                          \ leave input line
    8 2 do i police 2 +loop ;
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
 ok

Fortran

This uses the ability standardised in F90 of labelling a DO-loop so that its start and end are linked by usage of the same name, with this checked by the compiler. Further, in avoiding the use of the dreaded GO TO statement, the CYCLE statement can be employed instead with the same effect, and it too can bear the same name so that it is clear which loop is involved. These names prefix the DO-loop, and so, force some additional indentation. They are not statement labels and must be unique themselves. Notably, they cannot be the same text as the name of the index variable for their DO-loop, unlike the lead given by BASIC with its FOR I ... NEXT I arrangement.

The method is just to generate all the possibilities, discarding those that fail the specified tests. However, the requirement that the codes add up to twelve means that after the first two are chosen the third is determined, and blandly looping through all the possibilities is too much brute force and ignorance, though other collections of rules could make that bearable.

Since the modernisers of Fortran made a point of specifying that it does not specify the manner of evaluation of compound boolean expressions, specifically, that there is to be no reliance on Short-circuit_evaluation, both parts of the compound expression of the line labelled 5 "may" be evaluated even though the first may have determined the result. Prior to the introduction of LOGICAL variables with F66, one employed integer arithmetic as is demonstrated in the arithmetic-IF test of the line labelled 6. On the B6700, this usage ran faster than the corresponding boolean expression - possibly because there was no test for short-circuiting the expression when the first part of a multiply was zero...

Note that the syntax enables two classes of labels: the old-style numerical label in columns one to five, and the special label-like prefix of a DO-loop that is not in columns one to five. And yes, a line can have both.
      INTEGER P,S,F	!Department codes for Police, Sanitation, and Fire. Values 1 to 7 only.
    1  PP:DO P = 2,7,2	!The police demand an even number. They're special and use violence.
    2   SS:DO S = 1,7		!The sanitation department accepts any value.
    3        IF (P.EQ.S) CYCLE SS	!But it must differ from the others.
    4        F = 12 - (P + S)		!The fire department accepts any number, but the sum must be twelve.
    5        IF (F.LE.0 .OR. F.GT.7) CYCLE SS	!Ensure that the only option is within range.
    6        IF ((F - S)*(F - P)) 7,8,7		!And F is to differ from S and from P
    7        WRITE (6,"(3I2)") P,S,F		!If we get here, we have a possible set.
    8      END DO SS		!Next S
    9    END DO PP	!Next P.
      END	!Well, that was straightforward.

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

FreeBASIC

' version 15-08-2017
' compile with: fbc -s console

Dim As Integer fire, police, sanitation

Print "police fire sanitation"
Print "----------------------"

For police = 2 To 7 Step 2
    For fire = 1 To 7
        If fire = police Then Continue For
        sanitation = 12 - police - fire
        If sanitation = fire Or sanitation = police Then Continue For
        If sanitation >= 1 And sanitation <= 7 Then
            Print Using "   #     #       # "; police; fire; sanitation
        End If
    Next
Next

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
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 


FutureBasic

include "NSLog.incl"

void local fn DepartmentNumbers
  long police, sanitation, fire
  
  printf @"Police     Sanitation     Fire"
  printf @"-------------------------------"
  
  for police = 2 to 7 step 2
    for fire = 1 to 7
      if ( fire = police ) then continue
      sanitation = 12 - police - fire
      if ( sanitation == fire ) or ( sanitation == police ) then continue
      if ( sanitation >= 1 ) and ( sanitation <= 7 )
        printf @"%4d%12d%13d", police, fire, sanitation
      end if
    next
  next
end fn

window 1

fn DepartmentNumbers

HandleEvents
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


Gambas

Click this link to run this code

Public Sub Main()
Dim siC0, siC1, siC2 As Short
Dim sOut As New String[]
Dim sTemp As String

For siC0 = 2 To 6 Step 2
  For siC1 = 1 To 7
    For siC2 = 1 To 7
      If sic0 + siC1 + siC2 = 12 Then
        If siC0 <> siC1 And siC1 <> siC2 And siC0 <> siC2 Then sOut.Add(Str(siC0) & Str(siC1) & Str(siC2))
      End If
    Next
  Next
Next

Print "\tPolice\tFire\tSanitation"
siC0 = 0

For Each sTemp In sOut
  Inc sic0
  Print "[" & Format(Str(siC0), "00") & "]\t" & Left(sTemp, 1) & "\t" & Mid(sTemp, 2, 1) & "\t" & Right(sTemp, 1)
Next

End

Output:

        Police  Fire    Sanitation
[01]    2       3       7
[02]    2       4       6
[03]    2       6       4
[04]    2       7       3
[05]    4       1       7
[06]    4       2       6
[07]    4       3       5
[08]    4       5       3
[09]    4       6       2
[10]    4       7       1
[11]    6       1       5
[12]    6       2       4
[13]    6       4       2
[14]    6       5       1

Go

Translation of: Kotlin
package main

import "fmt"

func main() {
    fmt.Println("Police  Sanitation  Fire")
    fmt.Println("------  ----------  ----")
    count := 0
    for i := 2; i < 7; i += 2 {
        for j := 1; j < 8; j++ {
            if j == i { continue }
            for k := 1; k < 8; k++ {
                if k == i || k == j { continue }
                if i + j + k != 12 { continue }
                fmt.Printf("  %d         %d         %d\n", i, j, k)
                count++
            }
        }
    }
    fmt.Printf("\n%d valid combinations\n", count)
}
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

Groovy

Translation of: Java
class DepartmentNumbers {
    static void main(String[] args) {
        println("Police  Sanitation  Fire")
        println("------  ----------  ----")
        int count = 0
        for (int i = 2; i <= 6; i += 2) {
            for (int j = 1; j <= 7; ++j) {
                if (j == i) continue
                for (int k = 1; k <= 7; ++k) {
                    if (k == i || k == j) continue
                    if (i + j + k != 12) continue
                    println("  $i         $j         $k")
                    count++
                }
            }
        }
        println()
        println("$count valid combinations")
    }
}
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

GW-BASIC

10 PRINT "Police Sanitation Fire"
20 PRINT "------|----------|----"
30 FOR P = 2 TO 7 STEP 2
40 FOR S = 1 TO 7
50 IF S = P THEN GOTO 100
60 FOR F = 1 TO 7
70 IF S = F OR F = P THEN GOTO 90
80 IF P+S+F = 12 THEN PRINT USING "   #       #       #";P;F;S
90 NEXT F
100 NEXT S
110 NEXT P

Haskell

Bare minimum:

main :: IO ()
main =
  mapM_ print $
  [2, 4, 6] >>=
  \x ->
     [1 .. 7] >>=
     \y ->
        [12 - (x + y)] >>=
        \z ->
           case y /= z && 1 <= z && z <= 7 of
             True -> [(x, y, z)]
             _ -> []

or, resugaring this into list comprehension format:

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 ]

Do notation:

main :: IO ()
main =
  mapM_ print $
  do x <- [2, 4, 6]
     y <- [1 .. 7]
     z <- [12 - (x + y)]
     if y /= z && 1 <= z && z <= 7
       then [(x, y, z)]
       else []

Unadorned brute force – more than enough at this small scale:

import Data.List (nub)

main :: IO ()
main =
  let xs = [1 .. 7]
  in mapM_ print $
     xs >>=
     \x ->
        xs >>=
        \y ->
           xs >>=
           \z ->
              [ (x, y, z)
              | even x && 3 == length (nub [x, y, z]) && 12 == sum [x, y, z] ]
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:

-------------------- DEPARTMENT NUMBERS ------------------

options :: Int -> Int -> Int -> [(Int, Int, Int)]
options lo hi total =
  ( \ds ->
      filter even ds
        >>= \x ->
          filter (/= x) ds
            >>= \y ->
              [total - (x + y)]
                >>= \z ->
                  [ (x, y, z)
                    | y /= z && lo <= z && z <= hi
                  ]
  )
    [lo .. hi]

--------------------------- TEST -------------------------
main :: IO ()
main =
  let xs = options 1 7 12
   in putStrLn "(Police, Sanitation, Fire)\n"
        >> mapM_ print xs
        >> mapM_
          putStrLn
          [ "\nNumber of options: ",
            show (length xs)
          ]

Reaching again for a little more syntactic sugar, the options function above could also be re-written either as a list comprehension,

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 ]

or in Do notation:

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

J

Solution:

require 'stats'
permfrom=: ,/@(perm@[ {"_ 1 comb)  NB. get permutations of length x from y possible items

alluniq=: # = #@~.           NB. check items are unique
addto12=: 12 = +/            NB. check items add to 12
iseven=: -.@(2&|)            NB. check items are even
policeeven=: {.@iseven       NB. check first item is even
conditions=: policeeven *. addto12 *. alluniq

Validnums=: >: i.7           NB. valid Department numbers

getDeptNums=: [: (#~ conditions"1) Validnums {~ permfrom

Example usage:

   3 getDeptNums 7
4 1 7
4 7 1
6 1 5
6 5 1
2 3 7
2 7 3
2 4 6
2 6 4
4 2 6
4 6 2
6 2 4
6 4 2
4 3 5
4 5 3

Alternate approaches

   (/:"#. 2|]) (#~ 12=+/"1) 1+3 comb 7 [ load'stats'
4 1 7
6 1 5
2 3 7
2 4 6
4 3 5

Note that we are only showing the distinct valid combinations here, not all valid permutations of those combinations. (Valid permutations would be: swapping the last two values in a combination, and all permutations of 2 4 6.)

Another variation would be more constraint based, blindly implementing the rules of the task and yielding all valid permutations. (Shown here with the number of possibilities at each step):

     NB. 3 departments, 1..7 in each
     #rule1=. >,{3#<1+i.7
343
     NB. total must be 12, numbers must be unique
     #rule2=. (#~ ((3=#@~.) * 12=+/)"1) rule1
30
     NB. no odd numbers in police department (first department)
     #rule3=. (#~ 0=2|{."1) rule2
14
     rule3
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

Java

Translation of: Kotlin
public class DepartmentNumbers {
    public static void main(String[] args) {
        System.out.println("Police  Sanitation  Fire");
        System.out.println("------  ----------  ----");
        int count = 0;
        for (int i = 2; i <= 6; i += 2) {
            for (int j = 1; j <= 7; ++j) {
                if (j == i) continue;
                for (int k = 1; k <= 7; ++k) {
                    if (k == i || k == j) continue;
                    if (i + j + k != 12) continue;
                    System.out.printf("  %d         %d         %d\n", i, j, k);
                    count++;
                }
            }
        }
        System.out.printf("\n%d valid combinations", count);
    }
}
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

JavaScript

ES5

Briefly:

(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');
})();
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
(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);
})();
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:

(() => {
    "use strict";

    const
        label = "(Police, Sanitation, Fire)",
        solutions = [2, 4, 6]
        .flatMap(
            x => [1, 2, 3, 4, 5, 6, 7]
            .flatMap(
                y => [12 - (x + y)]
                .flatMap(
                    z => z !== y && 1 <= z && z <= 7 ? [
                        [x, y, z]
                    ] : []
                )
            )
        )
        .map(JSON.stringify)
        .join("\n");

    return `${label}\n${solutions}`;
})();
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
(() => {
    "use strict";

    // -------------- NUMBERING CONSTRAINTS --------------

    // options :: Int -> Int -> Int -> [(Int, Int, Int)]
    const options = lo => hi => total => {
        const
            bind = xs => f => xs.flatMap(f),
            ds = enumFromTo(lo)(hi);

        return bind(ds.filter(even))(
            x => bind(ds.filter(d => d !== x))(
                y => bind([total - (x + y)])(
                    z => (z !== y && lo <= z && z <= hi) ? [
                        [x, y, z]
                    ] : []
                )
            )
        );
    };

    // ---------------------- TEST -----------------------
    const main = () => {
        const
            label = "(Police, Sanitation, Fire)",
            solutions = options(1)(7)(12),
            n = solutions.length,
            list = solutions
            .map(JSON.stringify)
            .join("\n");

        return (
            `${label}\n\n${list}\n\nNumber of options: ${n}`
        );
    };

    // ---------------- GENERIC FUNCTIONS ----------------

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // even :: Integral a => a -> Bool
    const even = n => n % 2 === 0;

    // MAIN ---
    return main();
})();
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

jq

In this section, we present three solutions.

The first illustrates how a straightforward generate-and-test algorithm using familiar for-loops can be translated into jq.

The second illustrates how essentially the same algorithm can be written in a more economical way, without sacrificing comprehensibility.

The third illustrates how the built-in function `combinations/1' can be used to achieve greater efficiency.

The solutions in all cases are presented as a stream of JSON objects such as:

   {"fire":1,"police":4,"sanitation":7}

as these are self-explanatory, though it would be trivial to present them in another format. For brevity, the solutions are omitted here.

Nested for-loop

def check(fire; police; sanitation):
    (fire != police) and (fire != sanitation) and (police != sanitation)
    and (fire + police + sanitation == 12)
    and (police % 2 == 0);

range(1;8) as $fire
| range(1;8) as $police
| range(1;8) as $sanitation
| select( check($fire; $police; $sanitation) )
| {$fire, $police, $sanitation}

In Brief

{fire: range(1;8), police: range(1;8), sanitation: range(1;8)}
| select( .fire != .police and .fire != .sanitation and .police != .sanitation
      and .fire + .police + .sanitation == 12
      and .police % 2 == 0 )

combinations

  [range(1;8)]
  | combinations(3)
  | select( add == 12 and .[1] % 2 == 0)
  | {fire: .[0], police: .[1], sanitation: .[2]}

Julia

using Printf

function findsolution(rng=1:7)
    rst = Matrix{Int}(0, 3)
    for p in rng, f in rng, s in rng
        if p != s != f != p && p + s + f == 12 && iseven(p)
            rst = [rst; p s f]
        end
    end
    return rst
end

function printsolutions(sol::Matrix{Int})
    println("      Pol.   Fire   San.")
    println("      ----   ----   ----")
    for row in 1:size(sol, 1)
        @printf("%2i | %4i%7i%7i\n", row, sol[row, :]...)
    end
end

printsolutions(findsolution())
Output:
      Pol.   Fire   San.
      ----   ----   ----
 1 |    2      7      3
 2 |    2      6      4
 3 |    2      4      6
 4 |    2      3      7
 5 |    4      7      1
 6 |    4      6      2
 7 |    4      5      3
 8 |    4      3      5
 9 |    4      2      6
10 |    4      1      7
11 |    6      5      1
12 |    6      4      2
13 |    6      2      4
14 |    6      1      5

Kotlin

// 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")
}
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

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

MAD

           NORMAL MODE IS INTEGER
           PRINT COMMENT $ POLICE  SANITATION  FIRE$
           THROUGH LOOP, FOR P=2, 2, P.G.7
           THROUGH LOOP, FOR S=1, 1, S.G.7
           THROUGH LOOP, FOR F=1, 1, F.G.7
           WHENEVER P.E.S .OR. P.E.F .OR. S.E.F, TRANSFER TO LOOP
           WHENEVER P+S+F .E. 12, PRINT FORMAT OCC, P, S, F
LOOP       CONTINUE
           VECTOR VALUES OCC = $I6,S2,I10,S2,I4*$
           END OF PROGRAM
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

Maple

#determines if i, j, k are exclusive numbers
exclusive_numbers := proc(i, j, k)
	if (i = j) or (i = k) or (j = k) then
		return false;
	end if;
	return true;
end proc;

#outputs all possible combinations of numbers that statisfy given conditions
department_numbers := proc()
	local i, j, k;
	printf("Police		Sanitation	Fire\n");
	for i to 7 do
		for j to 7 do
			k := 12 - i - j;
			if (k <= 7) and (k >= 1) and (i mod 2 = 0) and exclusive_numbers(i,j,k) then
				printf("%d		%d		%d\n", i, j, k);
			end if;
		end do;
	end do;
end proc;

department_numbers();
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

Mathematica/Wolfram Language

Select[Permutations[Range[7], {3}], Total[#] == 12 && EvenQ[First[#]] &]
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}}


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

MiniScript

Translation of: Kotlin
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"
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

Modula-2

MODULE DepartmentNumbers;
FROM Conversions IMPORT IntToStr;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

PROCEDURE WriteInt(num : INTEGER);
VAR str : ARRAY[0..16] OF CHAR;
BEGIN
    IntToStr(num,str);
    WriteString(str);
END WriteInt;

VAR i,j,k,count : INTEGER;
BEGIN
    count:=0;

    WriteString("Police  Sanitation  Fire");
    WriteLn;
    WriteString("------  ----------  ----");
    WriteLn;

    FOR i:=2 TO 6 BY 2 DO
        FOR j:=1 TO 7 DO
            IF j=i THEN CONTINUE; END;
            FOR k:=1 TO 7 DO
                IF (k=i) OR (k=j) THEN CONTINUE; END;
                IF i+j+k # 12 THEN CONTINUE; END;
                WriteString("  ");
                WriteInt(i);
                WriteString("         ");
                WriteInt(j);
                WriteString("         ");
                WriteInt(k);
                WriteLn;
                INC(count);
            END;
        END;
    END;

    WriteLn;
    WriteInt(count);
    WriteString(" valid combinations");
    WriteLn;

    ReadChar;
END DepartmentNumbers.

Mercury

:- module department_numbers.
:- interface.

:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.

:- implementation.

:- import_module int, list, solutions, string.

main(!IO) :-
    io.print_line("P S F", !IO),
    unsorted_aggregate(department_number, print_solution, !IO).

:- pred print_solution({int, int, int}::in, io::di, io::uo) is det.

print_solution({P, S, F}, !IO) :-
    io.format("%d %d %d\n", [i(P), i(S), i(F)], !IO).

:- pred department_number({int, int, int}::out) is nondet.

department_number({Police, Sanitation, Fire}) :-
    list.member(Police, [2, 4, 6]),
    list.member(Sanitation, 1 .. 7),
    list.member(Fire, 1 .. 7),
    Police \= Sanitation,
    Police \= Fire,
    Sanitation \= Fire,
    Police + Sanitation + Fire = 12.
Output:
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

Nim

type Solution = tuple[p, s, f: int]

iterator solutions(max, total: Positive): Solution =
  for p in countup(2, max, 2):
    for s in 1..max:
      if s == p: continue
      let f = total - p - s
      if f notin [p, s] and f in 1..max:
        yield (p, s, f)

echo "P S F"
for sol in solutions(7, 12):
  echo sol.p, " ", sol.s, " ", sol.f
Output:
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

Objeck

Translation of: C++
class Program {
  function : Main(args : String[]) ~ Nil {
    sol := 1;
    "\t\tFIRE\tPOLICE\tSANITATION"->PrintLine();
    for( f := 1; f < 8; f+=1; ) {
      for( p := 1; p < 8; p+=1; ) {
        for( s:= 1; s < 8; s+=1; ) {
          if( f <> p & f <> s & p <> s & ( p and 1 ) = 0 & ( f + s + p = 12 ) ) {
            "SOLUTION #{$sol}: \t{$f}\t{$p}\t{$s}"->PrintLine();
            sol += 1;
          };
        };
      };
    };  
  }
}

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

OCaml

(*
 * Caution: This is my first Ocaml program and anyone with Ocaml experience probably thinks it's horrible
 *          So please don't use this as an example for "good ocaml code" see it more as 
 *          "this is what my first lines of ocaml might look like"
 *
 *          The only reason im publishing this is that nobody has yet submitted an example in ocaml
 *)


(* sfp is just a convenience to put a combination if sanitation (s) fire (f) and police (p) department in one record*)
type sfp = {s : int; f : int; p : int}

(* Convenience Function to print a single sfp Record *)
let print_sfp e =
    Printf.printf "%d %d %d\n" e.s e.f e.p

(* Convenience Function to print a list of sfp Records*)
let print_sfp_list l =
    l |> List.iter print_sfp

(* Computes sum of list l *)
let sum l = List.fold_left (+) 0 l

(* checks if element e is in list l *)
let element_in_list e l =
    l |> List.find_map (fun x -> if x == e then Some(e) else None) <> None

(* returns a list with only the unique elements of list l *)
let uniq l =
    let rec uniq_helper acc l =
        match l with
        | [] -> acc
        | h::t -> if element_in_list h t then uniq_helper acc t else uniq_helper (h::acc) t in
    uniq_helper [] l |> List.rev

(* checks wheter or not list l only contains unique elements *)
let is_uniq l = uniq l = l


(* computes all combinations for a given list of sanitation, fire & police departments 
   im not very proud of this function...maybe someone with some experience can clean it up? ;)
*)
let department_numbers sl fl pl =
    sl |> List.fold_left (fun aa s ->
        fl |> List.fold_left (fun fa f ->
            pl |> List.fold_left (fun pa p ->
                if
                    sum [s;f;p] == 12 &&
                    is_uniq [s;f;p] then
                        {s = s; f = f; p = p} :: pa
                else
                    pa) []
        |> List.append fa) []
    |> List.append aa) []


(* "main" function *)
let _ =
    let s = [1;2;3;4;5;6;7] in
    let f = [1;2;3;4;5;6;7] in
    let p = [2;4;6] in
    let result = department_numbers s f p in
    print_endline "S F P";
    print_sfp_list result;
Output:
S F P
1 5 6
1 7 4
2 4 6
2 6 4
3 5 4
3 7 2
4 2 6
4 6 2
5 1 6
5 3 4
6 2 4
6 4 2
7 1 4
7 3 2

PARI/GP

forstep(p=2,6,2, for(f=1,7, s=12-p-f; if(p!=f && p!=s && f!=s && s>0 && s<8, print(p" "f" "s))))
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

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";
      }
    }
  }	
}


Above Code cleaned up and shortened

#!/usr/bin/perl

use strict;   # Not necessary but considered good perl style
use warnings; # this one too

print "Police\t-\tFire\t-\tSanitation\n";
for my $p ( 1..7 )  # Police Department
{
  for my $f ( 1..7) # Fire Department
  {
    for my $s ( 1..7 ) # Sanitation Department
    {
      if ( $p % 2 == 0 && $p + $f + $s == 12 && $p != $f && $f != $s  && $s != $p && $f != $s) # Check if the combination of numbers is valid
      {
        print "$p\t-\t$f\t-\t$s\n";
      }
    }
  }
}

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

Alternate with Regex

#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Department_numbers
use warnings;

print "P S F\n\n";

'246 1234567 1234567' =~
  /(.).* \s .*?(?!\1)(.).* \s .*(?!\1)(?!\2)(.)
  (??{$1+$2+$3!=12})
  (?{ print "@{^CAPTURE}\n" })(*FAIL)/x;
Output:
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

Alternate with Glob

#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Department_numbers
use warnings;

print "P S F\n\n";

print tr/+/ /r, "\n" for
  grep  !/(\d).*\1/ && 12 == eval,
  glob '{2,4,6}' . '+{1,2,3,4,5,6,7}' x 2;

Output same as with Regex

Phix

printf(1,"Police  Sanitation  Fire\n")
printf(1,"------  ----------  ----\n")
integer solutions = 0
for police=2 to 7 by 2 do
    for sanitation=1 to 7 do
        if sanitation!=police then
            integer fire = 12-(police+sanitation)
            if fire>=1
            and fire<=7
            and fire!=police
            and fire!=sanitation then
                printf(1,"  %d         %d         %d\n", {police,sanitation,fire})
                solutions += 1
            end if
        end if
    end for
end for
printf(1,"\n%d solutions found\n", solutions)
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 solutions found

PHP

<?php

$valid = 0;
for ($police = 2 ; $police <= 6 ; $police += 2) {
    for ($sanitation = 1 ; $sanitation <= 7 ; $sanitation++) {
        $fire = 12 - $police - $sanitation;
        if ((1 <= $fire) and ($fire <= 7) and ($police != $sanitation) and ($sanitation != $fire)) {
            echo 'Police: ', $police, ', Sanitation: ', $sanitation, ', Fire: ', $fire, PHP_EOL;
            $valid++;
        }
    }
}
echo $valid, ' valid combinations found.', PHP_EOL;
Output:
Police: 2, Sanitation: 3, Fire: 7
Police: 2, Sanitation: 4, Fire: 6
Police: 2, Sanitation: 6, Fire: 4
Police: 2, Sanitation: 7, Fire: 3
Police: 4, Sanitation: 1, Fire: 7
Police: 4, Sanitation: 2, Fire: 6
Police: 4, Sanitation: 3, Fire: 5
Police: 4, Sanitation: 5, Fire: 3
Police: 4, Sanitation: 6, Fire: 2
Police: 4, Sanitation: 7, Fire: 1
Police: 6, Sanitation: 1, Fire: 5
Police: 6, Sanitation: 2, Fire: 4
Police: 6, Sanitation: 4, Fire: 2
Police: 6, Sanitation: 5, Fire: 1
14 valid combinations found.

Picat

Constraint model

import cp.

go ?=>
  N = 7,
  Sols = findall([P,S,F], department_numbers(N, P,S,F)),
  println(" P  S  F"),
  foreach([P,S,F] in Sols)
    printf("%2d %2d %2d\n",P,S,F)
  end,
  nl,
  printf("Number of solutions: %d\n", Sols.len),
  nl.
go => true.

department_numbers(N, Police,Sanitation,Fire) =>
   Police :: 1..N,
   Sanitation :: 1..N,
   Fire :: 1..N,
   all_different([Police,Sanitation,Fire]),
   Police + Sanitation + Fire #= 12,
   Police mod 2 #= 0,
   solve([Police,Sanitation,Fire]).
Output:
 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

Number of solutions: 14

Loop

go2 => department_numbers2(N) =>
  println(" P  S  F"),
  foreach(P in 1..N, P mod 2 == 0)
    foreach(S in 1..N, P != S)
      foreach(F in 1..N, F != P, F != S, P + S + F == 12)
         printf("%2d %2d %2d\n",P,S,F)
      end
    end
  end.

List comprehension

import util.

department_numbers3(N) =>
  println("P S F"),
  L = [[P.to_string,S.to_string,F.to_string] : P in 1..N, P mod 2 == 0,
        S in 1..N, P != S,
        F in 1..N,
        F != P, F != S, P + S + F == 12],
  println(map(L,join).join("\n")).

Prolog style

Translation of: Prolog
go :-
    println("P F S"),
    assign(Police, Fire, Sanitation),
    printf("%w %w %w\n", Police, Fire, Sanitation),
    fail,
    nl.

dept(X) :- between(1, 7, X).

police(X) :- member(X, [2, 4, 6]).
fire(X)   :- dept(X).
san(X)    :- dept(X).
 
assign(A, B, C) :-
    police(A), fire(B), san(C),
    A != B, A != C, B != C,
    12 is A + B + C.


PicoLisp

(de numbers NIL
   (co 'numbers
      (let N 7
         (for P N
            (for S N
               (for F N
                  (yield (list P S F)) ) ) ) ) ) )
(de departments NIL
   (use (L)
      (while (setq L (numbers))
         (or
            (bit? 1 (car L))
            (= (car L) (cadr L))
            (= (car L) (caddr L))
            (= (cadr L) (caddr L))
            (<> 12 (apply + L))
            (println L) ) ) ) )
(departments)
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)

Pilog

(be departments (@Pol @Fire @San)
   (member @Pol (2 4 6))
   (for @Fire 1 7)
   (for @San 1 7)
   (different @Pol @Fire)
   (different @Pol @San)
   (different @Fire @San)
   (^ @
      (= 12
         (+ (-> @Pol) (-> @Fire) (-> @San)) ) ) )
Output:
: (? (departments @Police @Fire @Sanitation))
 @Police=2 @Fire=3 @Sanitation=7
 @Police=2 @Fire=4 @Sanitation=6
 @Police=2 @Fire=6 @Sanitation=4
 @Police=2 @Fire=7 @Sanitation=3
 @Police=4 @Fire=1 @Sanitation=7
 @Police=4 @Fire=2 @Sanitation=6
 @Police=4 @Fire=3 @Sanitation=5
 @Police=4 @Fire=5 @Sanitation=3
 @Police=4 @Fire=6 @Sanitation=2
 @Police=4 @Fire=7 @Sanitation=1
 @Police=6 @Fire=1 @Sanitation=5
 @Police=6 @Fire=2 @Sanitation=4
 @Police=6 @Fire=4 @Sanitation=2
 @Police=6 @Fire=5 @Sanitation=1
-> NIL

Prolog

dept(X) :- between(1, 7, X).

police(X) :- member(X, [2, 4, 6]).
fire(X)   :- dept(X).
san(X)    :- dept(X).

assign(A, B, C) :-
    police(A), fire(B), san(C),
    A =\= B, A =\= C, B =\= C,
    12 is A + B + C.

main :-
    write("P F S"), nl,
    forall(assign(Police, Fire, Sanitation), format("~w ~w ~w~n", [Police, Fire, Sanitation])),
    halt.

?- main.
Output:
P F S
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

PL/M

Translation of: ALGOL W
Works with: 8080 PL/M Compiler
... under CP/M (or an emulator)
100H: /* SHOW POSSIBLE DEPARTMENT NUMBERS FOR POLICE, SANITATION AND FIRE    */
      /* THE POLICE DEPARTMENT NUMBER MUST BE EVEN, ALL DEPARTMENT NUMBERS   */
      /* MUST BE IN THE RANGE 1 .. 7 AND THE NUMBERS MUST SUM TO 12          */

   /* CP/M SYSTEM CALL AND I/O ROUTINES                                      */
   BDOS:      PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
   PR$CHAR:   PROCEDURE( C ); DECLARE C BYTE;    CALL BDOS( 2, C );  END;
   PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S );  END;
   PR$NL:     PROCEDURE;   CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
   PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH  */
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE;
      V = N;
      W = LAST( N$STR );
      N$STR( W ) = '$';
      N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END;
      CALL PR$STRING( .N$STR( W ) );
   END PR$NUMBER;

   /* TASK                                                                   */
   DECLARE MAX$DEPARTMENT$NUMBER LITERALLY '7';
   DECLARE DEPARTMENT$SUM        LITERALLY '12';
   DECLARE ( POLICE, SANITATION, FIRE ) BYTE;

   CALL PR$STRING( .'POLICE SANITATION FIRE$' );
   CALL PR$NL;

   DO POLICE = 2 TO MAX$DEPARTMENT$NUMBER BY 2;
      DO SANITATION = 1 TO MAX$DEPARTMENT$NUMBER;
         IF SANITATION <> POLICE THEN DO;
            FIRE = ( DEPARTMENT$SUM - POLICE ) - SANITATION;
            IF  FIRE <= MAX$DEPARTMENT$NUMBER
            AND FIRE <> SANITATION
            AND FIRE <> POLICE
            THEN DO;
               CALL PR$STRING( .'     $'      ); CALL PR$NUMBER( POLICE );
               CALL PR$STRING( .'          $' ); CALL PR$NUMBER( SANITATION );
               CALL PR$STRING( .'    $'       ); CALL PR$NUMBER( FIRE );
               CALL PR$NL;
            END;
         END;
      END;
   END;

EOF
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

Python

Procedural

from itertools import permutations
 
def solve():
    c, p, f, s = "\\,Police,Fire,Sanitation".split(',')
    print(f"{c:>3}  {p:^6} {f:^4} {s:^10}")
    c = 1
    for p, f, s in permutations(range(1, 8), r=3):
        if p + s + f == 12 and p % 2 == 0:
            print(f"{c:>3}: {p:^6} {f:^4} {s:^10}")
            c += 1
 
if __name__ == '__main__':
    solve()
Output:
  \  Police Fire Sanitation
  1:   2     3       7     
  2:   2     4       6     
  3:   2     6       4     
  4:   2     7       3     
  5:   4     1       7     
  6:   4     2       6     
  7:   4     3       5     
  8:   4     5       3     
  9:   4     6       2     
 10:   4     7       1     
 11:   6     1       5     
 12:   6     2       4     
 13:   6     4       2     
 14:   6     5       1     

Composition of pure functions

Expressing the options directly and declaratively in terms of a bind operator, without importing permutations:

Works with: Python version 3
'''Department numbers'''

from itertools import (chain)
from operator import (ne)


# options :: Int -> Int -> Int -> [(Int, Int, Int)]
def options(lo, hi, total):
    '''Eligible integer triples.'''
    ds = enumFromTo(lo)(hi)
    return bind(filter(even, ds))(
        lambda x: bind(filter(curry(ne)(x), ds))(
            lambda y: bind([total - (x + y)])(
                lambda z: [(x, y, z)] if (
                    z != y and lo <= z <= hi
                ) else []
            )
        )
    )


# TEST ----------------------------------------------------
# main :: IO ()
def main():
    '''Test'''

    xs = options(1, 7, 12)
    print(('Police', 'Sanitation', 'Fire'))
    for tpl in xs:
        print(tpl)
    print('\nNo. of options: ' + str(len(xs)))


# GENERIC ABSTRACTIONS ------------------------------------

# bind (>>=) :: [a] -> (a -> [b]) -> [b]
def bind(xs):
    '''List monad injection operator.
       Two computations sequentially composed,
       with any value produced by the first
       passed as an argument to the second.'''
    return lambda f: list(
        chain.from_iterable(
            map(f, xs)
        )
    )


# curry :: ((a, b) -> c) -> a -> b -> c
def curry(f):
    '''A curried function derived
       from an uncurried function.'''
    return lambda a: lambda b: f(a, b)


# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
    '''Integer enumeration from m to n.'''
    return lambda n: list(range(m, 1 + n))


# even :: Int -> Bool
def even(x):
    '''True if x is an integer
       multiple of two.'''
    return 0 == x % 2


if __name__ == '__main__':
    main()
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)

No. of options: 14

List comprehension

Nested bind (or concatMap) expressions (like those above) can also be translated into list comprehension notation:

Works with: Python version 3.7
'''Department numbers'''

from operator import ne


# options :: Int -> Int -> Int -> [(Int, Int, Int)]
def options(lo, hi, total):
    '''Eligible triples.'''
    ds = enumFromTo(lo)(hi)
    return [
        (x, y, z)
        for x in filter(even, ds)
        for y in filter(curry(ne)(x), ds)
        for z in [total - (x + y)]
        if y != z and lo <= z <= hi
    ]


# Or with less tightly-constrained generation,
# and more winnowing work downstream:

# options2 :: Int -> Int -> Int -> [(Int, Int, Int)]
def options2(lo, hi, total):
    '''Eligible triples.'''
    ds = enumFromTo(lo)(hi)
    return [
        (x, y, z)
        for x in ds
        for y in ds
        for z in [total - (x + y)]
        if even(x) and y not in [x, z] and lo <= z <= hi
    ]


# GENERIC -------------------------------------------------


# curry :: ((a, b) -> c) -> a -> b -> c
def curry(f):
    '''A curried function derived
       from an uncurried function.'''
    return lambda a: lambda b: f(a, b)


# enumFromTo :: (Int, Int) -> [Int]
def enumFromTo(m):
    '''Integer enumeration from m to n.'''
    return lambda n: list(range(m, 1 + n))


# even :: Int -> Bool
def even(x):
    '''True if x is an integer
       multiple of two.'''
    return 0 == x % 2


# unlines :: [String] -> String
def unlines(xs):
    '''A single string derived by the intercalation
       of a list of strings with the newline character.'''
    return '\n'.join(xs)


# TEST ----------------------------------------------------
# main :: IO ()
def main():
    '''Test'''

    xs = options(1, 7, 12)
    print(('Police', 'Sanitation', 'Fire'))
    print(unlines(map(str, xs)))
    print('\nNo. of options: ' + str(len(xs)))


if __name__ == '__main__':
    main()
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)

No. of options: 14 

Adapted from C# Example

# We start with the Police Department.
# Range is the start, stop, and step. This returns only even numbers.
for p in range(2, 7, 2):
    #Next, the Sanitation Department. A simple range.
    for s in range(1, 7):
        # And now the Fire Department. After determining the Police and Fire
        # numbers we just have to subtract those from 12 to get the FD number.
        f = 12 - p -s
        if s >= f: 
            break
        elif f > 7:
            continue
        print("Police: ", p, " Sanitation:", s, " Fire: ", f)
        print("Police: ", p, " Sanitation:", f, " Fire: ", s)
Output:
Police:  2  Sanitation: 3  Fire:  7
Police:  2  Sanitation: 7  Fire:  3
Police:  2  Sanitation: 4  Fire:  6
Police:  2  Sanitation: 6  Fire:  4
Police:  4  Sanitation: 1  Fire:  7
Police:  4  Sanitation: 7  Fire:  1
Police:  4  Sanitation: 2  Fire:  6
Police:  4  Sanitation: 6  Fire:  2
Police:  4  Sanitation: 3  Fire:  5
Police:  4  Sanitation: 5  Fire:  3
Police:  6  Sanitation: 1  Fire:  5
Police:  6  Sanitation: 5  Fire:  1
Police:  6  Sanitation: 2  Fire:  4
Police:  6  Sanitation: 4  Fire:  2


Using a constraint solver

A problem this trivial is amenable to brute-force solutions such as the above, but it is a good example of the type of problem for which a constraint solver can be useful. This is how one could solve it using the `python-constraint` library:

import constraint

depts = ( 'police', 'sanitation', 'fire' )

p = constraint.Problem()

for var in depts:
    p.addVariable(var, range(1,8))

p.addConstraint(constraint.AllDifferentConstraint())
p.addConstraint(lambda *vars: sum(vars)==12, depts)
p.addConstraint(lambda p: p%2==0, ('police',))

for s in p.getSolutions():
    print(s)
Output:
{'police': 6, 'fire': 5, 'sanitation': 1}
{'police': 6, 'fire': 4, 'sanitation': 2}
{'police': 6, 'fire': 2, 'sanitation': 4}
{'police': 6, 'fire': 1, 'sanitation': 5}
{'police': 4, 'fire': 6, 'sanitation': 2}
{'police': 4, 'fire': 7, 'sanitation': 1}
{'police': 4, 'fire': 5, 'sanitation': 3}
{'police': 4, 'fire': 3, 'sanitation': 5}
{'police': 4, 'fire': 2, 'sanitation': 6}
{'police': 4, 'fire': 1, 'sanitation': 7}
{'police': 2, 'fire': 4, 'sanitation': 6}
{'police': 2, 'fire': 6, 'sanitation': 4}
{'police': 2, 'fire': 7, 'sanitation': 3}
{'police': 2, 'fire': 3, 'sanitation': 7}

Quackery

Translation of: Forth
  [ 2dup = iff 
      [ 2drop drop ] done
    dip over swap over = iff
      [ 2drop drop ] done
    rot echo sp 
    swap echo sp 
    echo cr ]                is fire      ( pol san fir --> )

  [ 2dup = iff 2drop done
    12 over -
    dip over swap - 
    dup 1 < iff 
      [ 2drop drop ] done
    dup 7 > iff
      [ 2drop drop ] done
    fire ]                  is sanitation  (   pol san --> )

   [ 7 times 
       [ dup
         i^ 1+ sanitation ]
     drop ]                 is police      (       pol --> )

   [ cr ' [ 2 4 6 ]
     witheach police ]      is departments (           --> )

  departments
Output:
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

R

We solve this task in two lines. The rest of the code is to make the result look nice.

allPermutations <- setNames(expand.grid(seq(2, 7, by = 2), 1:7, 1:7), c("Police", "Sanitation", "Fire"))
solution <- allPermutations[which(rowSums(allPermutations)==12 & apply(allPermutations, 1, function(x) !any(duplicated(x)))),]
solution <- solution[order(solution$Police, solution$Sanitation),]
row.names(solution) <- paste0("Solution #", seq_len(nrow(solution)), ":")
print(solution)
Output:
              Police Sanitation Fire
Solution #1:       2          3    7
Solution #2:       2          4    6
Solution #3:       2          6    4
Solution #4:       2          7    3
Solution #5:       4          1    7
Solution #6:       4          2    6
Solution #7:       4          3    5
Solution #8:       4          5    3
Solution #9:       4          6    2
Solution #10:      4          7    1
Solution #11:      6          1    5
Solution #12:      6          2    4
Solution #13:      6          4    2
Solution #14:      6          5    1

Racket

We filter the Cartesian product of the lists of candidate department numbers.

#lang racket
(cons '(police fire sanitation)
      (filter (λ (pfs) (and (not (check-duplicates pfs))
                            (= 12 (apply + pfs))
                            pfs))
              (cartesian-product (range 2 8 2) (range 1 8) (range 1 8))))
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))

Raku

(formerly Perl 6)

for (1..7).combinations(3).grep(*.sum == 12) {
    for   .permutations\  .grep(*.[0] %%  2) {
        say <police fire sanitation> Z=> .list;
    }
}
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

This REXX example essentially uses brute force approach for so simple a puzzle.

/*REXX program finds/displays all possible variants of (3) department numbering  puzzle.*/
say 'police sanitation fire'                     /*display simple title   for the output*/
say '══════ ══════════ ════'                     /*   "     head separator "   "    "   */
#=0                                              /*number of solutions found  (so far). */
    do     p=1  for 7;     if p//2  then iterate /*try numbers for the police department*/
      do   s=1  for 7;     if s==p  then iterate /* "     "     "   "  fire        "    */
        do f=1  for 7;     if f==s  then iterate /* "     "     "   "  sanitation  "    */
        if p + s + f \== 12         then iterate /*check if sum of department nums ¬= 12*/
        #= # + 1                                 /*bump count of the number of solutions*/
        say center(p,6) center(s,10) center(f,4) /*display one possible solution.       */
        end   /*s*/
      end     /*f*/
    end       /*p*/

say '══════ ══════════ ════'                     /*   "     head separator "   "    "   */
say                                              /*stick a fork in it,  we're all done. */
say #  ' solutions found.'                       /*also, show the # of solutions found. */
output   when using the default inputs:
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  solutions found.

Ring

sanitation= 0
see "police fire sanitation" + nl

for police = 2 to 7 step 2
    for fire = 1 to 7
        if fire = police
           loop
        ok
        sanitation = 12 - police - fire
        if sanitation = fire or sanitation = police 
           loop
        ok  
        if sanitation >= 1 and sanitation <= 7 
           see "   " + police + "      " + fire + "       " + sanitation + nl
        ok
    next
next

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

RPL

≪ { } 
   2 6 FOR police
      1 7 FOR sanitation 
        IF police sanitation ≠ THEN 
           12 police - sanitation -
           IF DUP 0 > 
              OVER 7 ≤ AND 
              OVER police ≠ AND 
              OVER sanitation ≠ AND 
           THEN 
              police sanitation ROT 
              3 →ARRY + 
           ELSE DROP END 
        END 
     NEXT 
  2 STEP
  DUP SIZE
≫ 'PSF' STO
Output:
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

Ruby

(1..7).to_a.permutation(3){|p| puts p.join if p.first.even? && p.sum == 12 }
Output:
237
246
264
273
417
426
435
453
462
471
615
624
642
651

Rust

Translation of: C
extern crate num_iter;
fn main() {
    println!("Police Sanitation Fire");
    println!("----------------------");

    for police in num_iter::range_step(2, 7, 2) {
        for sanitation in 1..8 {
            for fire in 1..8 {
                if police != sanitation
                    && sanitation != fire
                    && fire != police
                    && police + fire + sanitation == 12
                {
                    println!("{:6}{:11}{:4}", police, sanitation, fire);
                }
            }
        }
    }
}

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") )
}
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)

Sidef

Translation of: Raku
@(1..7)->combinations(3, {|*a|
    a.sum == 12 || next
    a.permutations {|*b|
        b[0].is_even || next
        say (%w(police fire sanitation) ~Z b -> join(" "))
    }
})
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]

Swift

Functional approach:

let res = [2, 4, 6].map({x in
  return (1...7)
      .filter({ $0 != x })
      .map({y -> (Int, Int, Int)? in
        let z = 12 - (x + y)

        guard y != z && 1 <= z && z <= 7 else {
          return nil
        }

        return (x, y, z)
      }).compactMap({ $0 })
}).flatMap({ $0 })

for result in res {
  print(result)
}

Iterative approach:

var res = [(Int, Int, Int)]()

for x in [2, 4, 6] {
  for y in 1...7 where x != y {
    let z = 12 - (x + y)

    guard y != z && 1 <= z && z <= 7 else {
      continue
    }

    res.append((x, y, z))
  }
}

for result in res {
  print(result)
}
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)

Tcl

Since Tool Command Language is a multi-paradigm language, very different solutions are possible.

VERSION A - using procedures and list operations

# Procedure named ".." returns list of integers from 1 to max.
proc .. max {
  for {set i 1} {$i <= $max} {incr i} {
    lappend l $i
  }
  return $l
}

# Procedure named "anyEqual" returns true if any elements are equal,
# false otherwise.
proc anyEqual l {
  if {[llength [lsort -unique $l]] != [llength $l]} {
    return 1
  }
  return 0
}

# Procedure named "odd" tells whether a value is odd or not.
proc odd n {
  expr $n %2 != 0
}


# Procedure named "sum" sums its parameters.
proc sum args {
  expr [join $args +]
}


# Create lists of candidate numbers using proc ".."
set sanitation [.. 7]
set fire $sanitation
# Filter even numbers for police stations (remove odd ones).
set police [lmap e $sanitation {
  if [odd $e] continue
  set e
}]


# Try all combinations and display acceptable ones.
set valid 0
foreach p $police {
  foreach s $sanitation {
    foreach f $fire {
      # Check for equal elements in list.
      if [anyEqual [list $p $s $f]] continue
      # Check for sum of list elements.
      if {[sum $p $s $f] != 12} continue
      puts "$p $s $f"
      incr valid
    }
  }
}
puts "$valid valid combinations found."

VERSION B - using simple for loops with number literals

set valid 0
for {set police 2} {$police <= 6} {incr police 2} {
  for {set sanitation 1} {$sanitation <= 7} {incr sanitation} {
    if {$police == $sanitation} continue
    for {set fire 1} {$fire <= 7} {incr fire} {
      if {$police == $fire || $sanitation == $fire} continue
      if {[expr $police + $sanitation + $fire] != 12} continue
      puts "$police $sanitation $fire"
      incr valid
    }
  }
}
puts "$valid valid combinations found."

VERSION C - using simple for loops with number variables

set min 1
set max 7
set valid 0
for {set police $min} {$police <= $max} {incr police} {
  if {[expr $police % 2] == 1} continue ;# filter even numbers for police
  for {set sanitation $min} {$sanitation <= $max} {incr sanitation} {
    if {$police == $sanitation} continue
    for {set fire $min} {$fire <= $max} {incr fire} {
      if {$police == $fire || $sanitation == $fire} continue
      if {[expr $police + $sanitation + $fire] != 12} continue
      puts "$police $sanitation $fire"
      incr valid
    }
  }
}

puts "$valid valid combinations found."

VERSION D - using list filter with lambda expressions

# Procedure named ".." returns list of integers from 1 to max.
proc .. max {
  for {set i 1} {$i <= $max} {incr i} {
    lappend l $i
  }
  return $l
}


# Procedure named "..." returns list of n lists of integers from 1 to max.
proc ... {max n} {
  foreach i [.. $n] {
    lappend result [.. $max]
  }
  return $result
}

# Procedure named "crossProduct" returns cross product of lists
proc crossProduct {listOfLists} {
  set result [list [list]]
  foreach factor $listOfLists {
    set newResult {}
    foreach combination $result {
      foreach elt $factor {
        lappend newResult [linsert $combination end $elt]
      }
    }
    set result $newResult
  }
  return $result
}

# Procedure named "filter" filters list elements by using a 
# condition λ (lambda) expression
proc filter {l condition} {
  return [lmap el $l {
    if {![apply $condition $el]} continue
    set el
  }]
}

# Here the fun using lambda expressions begins. The following is the main program.

# Set λ expressions
set λPoliceEven {_ {expr [lindex $_ 0] % 2 == 0}}
set λNoEquals {_ {expr [llength [lsort -unique $_]] == [llength $_]}}
set λSumIs12 {_ {expr [join $_ +] == 12}}

# Create all combinations and filter acceptable ones
set numbersOk [filter [filter [filter [crossProduct [... 7 3]] ${λPoliceEven}] ${λSumIs12}] ${λNoEquals}]
puts [join $numbersOk \n]
puts "[llength $numbersOk] valid combinations found."
Output:

All four versions (A, B, C and D) produce the same result:

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

Tiny BASIC

   PRINT "Police Sanitation Fire"
   PRINT "------|----------|----"
10 LET P = P + 2
   LET S = 0
20 LET S = S + 1
   LET F = 0
   IF S = P THEN GOTO 20
30 LET F = F + 1
   IF S = F THEN GOTO 30
   IF F = P THEN GOTO 30
   IF P + S + F = 12 THEN PRINT "  ",P,"        ", S,"       ", F
   IF F < 7 THEN GOTO 30
   IF S < 7 THEN GOTO 20
   IF P < 6 THEN GOTO 10

Transd

#lang transd

MainModule : {
    _start: (lambda 
        (lout "Police | Sanit. | Fire")
        (for i in Range(1 8) where (not (mod i 2)) do
            (for j in Range(1 8) where (neq i j) do
                (for k in Range(1 8) where (and (neq i k) (neq j k)) do
           (if (eq (+ i j k) 12) (lout i "        " j "        " k)))))
    )
}
Output:
Police | Sanit. | 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

TypeScript

Translation of: Sinclair ZX81 BASIC
// Department numbers
console.log(`POLICE SANITATION FIRE`);
let f: number;
for (var p = 2; p <= 7; p += 2) {
  for (var s = 1; s <= 7; s++) {
    if (s != p) {      
      f = (12 - p) - s;
      if ((f > 0) && (f <= 7) && (f != s) && (f != p))
        console.log(`   ${p}       ${s}       ${f}`);
    }
  }
}
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

UNIX Shell

Works with: Bourne Again SHell
Works with: Korn Shell
Works with: Z Shell
function main {
  set -- Police Sanitation Fire
  typeset -i pw=${#1} sw=${#2} fw=${#3}
  printf '%s' "$1"
  shift
  printf '\t%s' "$@"
  printf '\n'
  for (( p=2; p<8; p+=2 )); do
    for (( s=1; s<8; ++s )); do
      if (( s == p )); then
        continue
      fi
      (( f = 12 - p - s ))
      if (( f == s || f == p || f < 1 || f > 7 )); then
        continue
      fi
      printf "%${pw}d\t%${sw}d\t%${fw}d\n" "$p" "$s" "$f"
    done
  done
}

main "$@"
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


Visual Basic .NET

Translation of: C#
Module Module1

    Sub Main()
        For p = 2 To 7 Step 2
            For s = 1 To 7
                Dim f = 12 - p - s
                If s >= f Then
                    Exit For
                End If
                If f > 7 Then
                    Continue For
                End If
                If s = p OrElse f = p Then
                    Continue For 'not even necessary
                End If
                Console.WriteLine($"Police:{p}, Sanitation:{s}, Fire:{f}")
                Console.WriteLine($"Police:{p}, Sanitation:{f}, Fire:{s}")
            Next
        Next
    End Sub

End Module
Output:
Police:2, Sanitation:3, Fire:7
Police:2, Sanitation:7, Fire:3
Police:2, Sanitation:4, Fire:6
Police:2, Sanitation:6, Fire:4
Police:4, Sanitation:1, Fire:7
Police:4, Sanitation:7, Fire:1
Police:4, Sanitation:2, Fire:6
Police:4, Sanitation:6, Fire:2
Police:4, Sanitation:3, Fire:5
Police:4, Sanitation:5, Fire:3
Police:6, Sanitation:1, Fire:5
Police:6, Sanitation:5, Fire:1
Police:6, Sanitation:2, Fire:4
Police:6, Sanitation:4, Fire:2

V (Vlang)

Translation of: Go
fn main() {
    println("Police  Sanitation  Fire")
    println("------  ----------  ----")
    mut count := 0
    for i := 2; i < 7; i += 2 {
        for j in 1..8 {
            if j == i { continue }
            for k in 1..8 {
                if k == i || k == j { continue }
                if i + j + k != 12 { continue }
                println("  $i         $j         $k")
                count++
            }
        }
    }
    println("\n$count valid combinations")
}
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

VTL-2

10 P=2
20 S=1
30 F=1
40 #=0<((P=S)+(P=F)+(S=F)+(P+S+F=12=0))*110
50 ?=P
60 $=32
70 ?=S
80 $=32
90 ?=F
100 ?=""
110 F=F+1
120 #=F<8*40
130 S=S+1
140 #=S<8*30
150 P=P+2
160 #=P<8*20
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

Wren

Translation of: Kotlin
System.print("Police  Sanitation  Fire")
System.print("------  ----------  ----")
var count = 0
for (h in 1..3) {
    var i = h * 2
    for (j in 1..7) {
        if (j != i) {
            for (k in 1..7) {
                if ((k != i && k != j) && (i + j + k == 12) ) {
                    System.print("  %(i)         %(j)         %(k)")
                    count = count + 1
                }
            }
        }
    }
}
System.print("\n%(count) valid combinations")
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

XPL0

Translation of: Sinclair ZX81 BASIC
Works with: EXPL-32
\Department numbers
code CrLf=9, IntIn=10, IntOut=11, Text=12;
integer P, S, F;

begin
Text(0, "POLICE SANITATION FIRE");
CrLf(0);
P:= 2;
while P <= 7 do
  begin
  for S:= 1, 7 do
    if S # P then
      begin
      F:= (12 - P) - S;
      if (F > 0) & (F <= 7) & (F # S) & (F # P) then
        begin
        Text(0, "   "); IntOut(0, P); 
        Text(0, "       "); IntOut(0, S);
        Text(0, "       "); IntOut(0, F); 
        CrLf(0)
        end
      end;
  P:= P + 2
  end;
end
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

Zig

Works with: Zig version 0.11.0dev
const std = @import("std");
pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.writeAll("Police  Sanitation  Fire\n");
    try stdout.writeAll("------  ----------  ----\n");

    var p: usize = 2;
    while (p <= 7) : (p += 2)
        for (1..7 + 1) |s|
            for (1..7 + 1) |f|
                if (p != s and s != f and f != p and p + f + s == 12) {
                    try stdout.print("  {d}         {d}         {d}\n", .{ p, s, f });
                };
}
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

Zig using an iterator

Works with: Zig version 0.11.0

Using a Zig struct to create an iterator is a common pattern in Zig.

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    try stdout.writeAll("Police  Sanitation  Fire\n");
    try stdout.writeAll("------  ----------  ----\n");

    var it = SolutionIterator.init();
    while (it.next()) |solution| {
        try stdout.print(
            "  {d}         {d}         {d}\n",
            .{ solution.police, solution.sanitation, solution.fire },
        );
    }
}

/// 3 bit unsigned (u3) limits 0 <= department <= 7
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) {
            const ov = @addWithOverflow(self.u.together, 1);
            if (ov[1] == 1) {
                self.u.together = 0;
                return null; // overflowed, completed
            } else {
                self.u.together = ov[0];
                // None can be zero
                if (self.u.departments.police == 0) self.u.departments.police = 2; // even
                if (self.u.departments.sanitation == 0) self.u.departments.sanitation = 1;
                if (self.u.departments.fire == 0) self.u.departments.fire = 1;
                // Police must be even
                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;
            }
        }
    }
};

zkl

Utils.Helpers.pickNFrom(3,[1..7].walk())    // 35 combos
.filter(fcn(numbers){ numbers.sum(0)==12 }) // which all sum to 12 (==5)
.println();
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:

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