Dinesman's multiple-dwelling problem: Difference between revisions
Dinesman's multiple-dwelling problem (view source)
Revision as of 01:49, 22 March 2024
, 1 month agoAdded various BASIC dialects (Chipmunk Basic, QBasic and True BASIC)
No edit summary |
(Added various BASIC dialects (Chipmunk Basic, QBasic and True BASIC)) |
||
(32 intermediate revisions by 20 users not shown) | |||
Line 24:
''Where does everyone live?''<br>
<br><br>
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">-V
BAKER = 0
COOPER = 1
FLETCHER = 2
MILLER = 3
SMITH = 4
names = [‘Baker’, ‘Cooper’, ‘Fletcher’, ‘Miller’, ‘Smith’]
V floors = Array(1..5)
L
I floors[BAKER] != 5 &
floors[COOPER] != 1 &
floors[FLETCHER] !C (1, 5) &
floors[MILLER] > floors[COOPER] &
abs(floors[SMITH] - floors[FLETCHER]) != 1 &
abs(floors[FLETCHER] - floors[COOPER]) != 1
L(floor) floors
print(names[L.index]‘ lives on floor ’floor)
L.break
I !floors.next_permutation()
print(‘No solution found.’)
L.break</syntaxhighlight>
{{out}}
<pre>
Baker lives on floor 3
Cooper lives on floor 2
Fletcher lives on floor 4
Miller lives on floor 5
Smith lives on floor 1
</pre>
=={{header|Ada}}==
Line 29 ⟶ 66:
Problem is easily changed by altering subtype Floor, type people and the somewhat naturally reading constraints in the Constrained function.
If for example you change the floor range to 1..6 and add Superman to people, all possible solutions will be printed.
<
procedure Dinesman is
subtype Floor is Positive range 1 .. 5;
Line 74 ⟶ 111:
end loop;
Solve (thefloors'Access, Floors'Length);
end Dinesman;</
{{out}}
<pre>BAKER on floor 3
Line 87 ⟶ 124:
The constraints for each person could be changed by providing a different PROC(INT)BOOL in the initialisation of the inhabitants.
Changing the number of inhabitants would require adding or removing loops from the solution finding code.
<
# SETUP #
Line 156 ⟶ 193:
FI
OD
OD</
{{out}}
<pre>
Line 165 ⟶ 202:
0 Smith
</pre>
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">on Dinesman()
set output to {}
(* American floor numbering used in these comments to match AppleScript's 1-based indices. *)
-- Baker's not on the fifth floor.
repeat with Baker from 1 to 4
-- Cooper's not on the first floor. Nor on the fifth as Miller's somewhere above him.
-- Fletcher's also not on these floors, so both are in the middle three. They're also
-- at least two floors apart, so one must be on the second and the other on the fourth.
repeat with Cooper from 2 to 4 by 2
if (Cooper ≠ Baker) then
set Fletcher to 6 - Cooper
-- Miller's somewhere above Cooper.
if (Fletcher ≠ Baker) then repeat with Miller from (Cooper + 1) to 5
-- Try to fit Smith in somewhere not adjacent to Fletcher.
if ((Miller ≠ Fletcher) and (Miller ≠ Baker)) then repeat with Smith from 1 to 5
if ((Smith is not in {Baker, Cooper, Fletcher, Miller}) and ¬
((Fletcher - Smith > 1) or (Smith - Fletcher > 1))) then
tell {missing value, missing value, missing value, missing value, missing value}
set {item Baker, item Cooper, item Fletcher, item Miller, item Smith} to ¬
{"Baker", "Cooper", "Fletcher", "Miller", "Smith"}
set end of output to {bottomToTop:it}
end tell
end if
end repeat
end repeat
end if
end repeat
end repeat
return {numberOfSolutions:(count output), solutions:output}
end Dinesman
return Dinesman()</syntaxhighlight>
{{output}}
<syntaxhighlight lang="applescript">{numberOfSolutions:1, solutions:{{bottomToTop:{"Smith", "Cooper", "Baker", "Fletcher", "Miller"}}}}</syntaxhighlight>
=={{header|AutoHotkey}}==
Line 170 ⟶ 245:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f DINESMANS_MULTIPLE-DWELLING_PROBLEM.AWK
BEGIN {
Line 210 ⟶ 285:
}
function abs(x) { if (x >= 0) { return x } else { return -x } }
</syntaxhighlight>
{{out}}
<pre>
Line 220 ⟶ 295:
</pre>
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">print "Los apartamentos están numerados del 0 (bajo) al 4 (ático)."
print "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
print "- Baker no vive en el último apartamento (ático)."
print "- Cooper no vive en el piso inferior (bajo)."
print "- Fletcher no vive ni en el ático ni en el bajo."
print "- Miller vive en un apartamento más alto que Cooper."
print "- Smith no vive en un apartamento adyacente al de Fletcher."
print "- Fletcher no vive en un apartamento adyacente al de Cooper." & chr(10)
for Baker = 0 to 3
for Cooper = 1 to 4
for Fletcher = 1 to 3
for Miller = 0 to 4
for Smith = 0 to 4
if Baker<>Cooper and Baker<>Fletcher and Baker<>Miller and Baker<>Smith and Cooper<>Fletcher and Cooper<>Miller and Cooper<>Smith and Fletcher<>Miller and Fletcher<>Smith and Miller<>Smith and Miller>Cooper and abs(Smith-Fletcher)<>1 and abs(Fletcher-Cooper)<>1 then
print "Baker vive en el piso "; Baker
print "Cooper vive en el piso "; Cooper
print "Fletcher vive en el piso "; Fletcher
print "Miller vive en el piso "; Miller
print "Smith vive en el piso "; Smith
end if
next Smith
next Miller
next Fletcher
next Cooper
next Baker
end</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
Each of the statements is represented by an equivalent conditional expression ('''stmt1$''', '''stmt2$''' etc.) as indicated in the comments, where the variables '''Baker''', '''Cooper''' etc. evaluate to the appropriate floor number. So long as each statement can be expressed in this way, and there is a unique solution, changes to the problem text can be accommodated.
<
REM "Baker, Cooper, Fletcher, Miller, and Smith live on different floors":
Line 271 ⟶ 382:
NEXT Cooper
NEXT Baker
END</
{{out}}
<pre>
Line 280 ⟶ 391:
Smith lives on floor 0
</pre>
==={{header|Chipmunk Basic}}===
{{trans|FreeBASIC}}
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="vbnet">100 cls
110 print "Los apartamentos están numerados del 0 (bajo) al 4 (ático)."
120 print "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
130 print "- Baker no vive en el último apartamento (ático)."
140 print "- Cooper no vive en el piso inferior (bajo)."
150 print "- Fletcher no vive ni en el ático ni en el bajo."
160 print "- Miller vive en un apartamento más alto que Cooper."
170 print "- Smith no vive en un apartamento adyacente al de Fletcher."
180 print "- Fletcher no vive en un apartamento adyacente al de Cooper."
190 print
200 for baker = 0 to 3
210 for cooper = 1 to 4
220 for fletcher = 1 to 3
230 for miller = 0 to 4
240 for smith = 0 to 4
250 if baker <> cooper and baker <> fletcher and baker <> miller and baker <> smith and cooper <> fletcher then
260 if cooper <> miller and cooper <> smith and fletcher <> miller and fletcher <> smith and miller <> smith then
270 if miller > cooper and abs(smith-fletcher) <> 1 and abs(fletcher-cooper) <> 1 then
280 print "Baker vive en el piso ";baker
290 print "Cooper vive en el piso ";cooper
300 print "Fletcher vive en el piso ";fletcher
310 print "Miller vive en el piso ";miller
320 print "Smith vive en el piso ";smith
330 endif
340 endif
350 endif
360 next smith
370 next miller
380 next fletcher
390 next cooper
400 next baker
410 end</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
==={{header|Commodore BASIC}}===
The statements have been rearranged below so as to eliminate the maximum number of iterations; they could all be placed in the innermost loop and achieve the same result, just more slowly.
<syntaxhighlight lang="basic">100 T=5:REM TOP FLOOR
110 FOR B=1 TO T
120 : REM BAKER DOES NOT LIVE ON THE TOP FLOOR
130 : IF B=T THEN 420
140 : FOR C=1 TO T
150 : IF C=B THEN 410: REM ONE PERSON PER FLOOR
160 : REM COOPER DOES NOT LIVE ON THE BOTTOM FLOOR
170 : IF C=1 THEN 410
180 : FOR F=1 TO T
190 : IF F=B OR F=C THEN 400: REM ONE PERSON PER FLOOR
200 : REM FLETCHER DOES NOT LIVE ON TOP OR BOTTOM
210 : IF F=1 OR F=T THEN 400
220 : REM FLETCHER DOES NOT LIVE ADJACENT TO COOPER
230 : IF ABS(F-C)=1 THEN 400
240 : FOR M=1 TO T
250 : IF M=B OR M=C OR M=F THEN 390: REM ONE PERSON PER FLOOR
260 : REM MILLER LIVES ABOVE COOPER
270 : IF M < C THEN 390
280 : FOR S=1 TO T
290 : IF S=B OR S=C OR S=F OR S=M THEN 380: REM ONE PERSON PER FLOOR
300 : REM SMITH DOES NOT LIVE ADJACENT TO FLETCHER
310 : IF ABS(F-S)=1 THEN 380
320 : PRINT "BAKER IS ON"B
330 : PRINT "COOPER IS ON"C
340 : PRINT "FLETCHER IS ON"F
350 : PRINT "MILLER IS ON"M
360 : PRINT "SMITH IS ON"S
370 : END
380 : NEXT S
390 : NEXT M
400 : NEXT F
410 : NEXT C
420 NEXT B
430 PRINT "NO SOLUTION"</syntaxhighlight>
{{Out}}
<pre>BAKER IS ON 3
COOPER IS ON 2
FLETCHER IS ON 4
MILLER IS ON 5
SMITH IS ON 1</pre>
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">Print "Los apartamentos estan numerados del 0 (bajo) al 4 (atico)."
Print "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
Print "- Baker no vive en el ultimo apartamento (atico)."
Print "- Cooper no vive en el piso inferior (bajo)."
Print "- Fletcher no vive ni en el atico ni en el bajo."
Print "- Miller vive en un apartamento más alto que Cooper."
Print "- Smith no vive en un apartamento adyacente al de Fletcher."
Print "- Fletcher no vive en un apartamento adyacente al de Cooper." & Chr(10)
Dim As Ubyte Baker, Cooper, Fletcher, Miller, Smith
For Baker = 0 To 3
For Cooper = 1 To 4
For Fletcher = 1 To 3
For Miller = 0 To 4
For Smith = 0 To 4
If Baker<>Cooper And Baker<>Fletcher And Baker<>Miller _
And Baker<>Smith And Cooper<>Fletcher And Cooper<>Miller _
And Cooper<>Smith And Fletcher<>Miller And Fletcher<>Smith _
And Miller<>Smith And Miller>Cooper And Abs(Smith-Fletcher)<>1 _
And Abs(Fletcher-Cooper)<>1 Then
Print "Baker vive en el piso "; Baker
Print "Cooper vive en el piso "; Cooper
Print "Fletcher vive en el piso "; Fletcher
Print "Miller vive en el piso "; Miller
Print "Smith vive en el piso "; Smith
End If
Next Smith
Next Miller
Next Fletcher
Next Cooper
Next Baker
Sleep</syntaxhighlight>
{{out}}
<pre>
Los apartamentos estan numerados del 0 (bajo) al 4 (atico).
Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes.
- Baker no vive en el ultimo apartamento (atico).
- Cooper no vive en el piso inferior (bajo).
- Fletcher no vive ni en el atico ni en el bajo.
- Miller vive en un apartamento mßs alto que Cooper.
- Smith no vive en un apartamento adyacente al de Fletcher.
- Fletcher no vive en un apartamento adyacente al de Cooper.
Baker vive en el piso 2
Cooper vive en el piso 1
Fletcher vive en el piso 3
Miller vive en el piso 4
Smith vive en el piso 0
</pre>
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "Dinesman.bas"
110 PRINT "Floors are numbered 0 (ground) to 4 (top).":PRINT "Baker, Cooper, Fletcher, Miller, and Smith live on different floors."
120 PRINT "- Baker does not live on the top floor.":PRINT "- Cooper does not live on the bottom floor."
130 PRINT "- Fletcher does not live on either the top or the bottom floor.":PRINT "- Miller lives on a higher floor than does Cooper."
140 PRINT "- Smith does not live on a floor adjacent to Fletcher's.":PRINT "- Fletcher does not live on a floor adjacent to Cooper's.":PRINT :LET S$=" lives on floor"
150 FOR B=0 TO 3
150 FOR C=1 TO 4
170 FOR F=1 TO 3
180 FOR M=0 TO 4
190 FOR S=0 TO 4
200 IF B<>C AND B<>F AND B<>M AND B<>S AND C<>F AND C<>M AND C<>S AND F<>M AND F<>S AND M<>S AND M>C AND ABS(S-F)<>1 AND ABS(F-C)<>1 THEN
210 PRINT "Baker",S$;B:PRINT "Cooper",S$;C:PRINT "Fletcher";S$;F:PRINT "Miller",S$;M:PRINT "Smith",S$;S
220 END
230 END IF
240 NEXT
250 NEXT
260 NEXT
270 NEXT
280 NEXT</syntaxhighlight>
==={{header|PureBasic}}===
{{incomplete|PureBasic|Examples should state what changes to the problem text are allowed.}}
<syntaxhighlight lang="purebasic">Prototype cond(Array t(1))
Enumeration #Null
#Baker
#Cooper
#Fletcher
#Miller
#Smith
EndEnumeration
Procedure checkTenands(Array tenants(1), Array Condions.cond(1))
Protected i, j
Protected.cond *f
j=ArraySize(Condions())
For i=0 To j
*f=Condions(i) ; load the function pointer to the current condition
If *f(tenants()) = #False
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
EndProcedure
Procedure C1(Array t(1))
If Int(Abs(t(#Fletcher)-t(#Cooper)))<>1
ProcedureReturn #True
EndIf
EndProcedure
Procedure C2(Array t(1))
If t(#Baker)<>5
ProcedureReturn #True
EndIf
EndProcedure
Procedure C3(Array t(1))
If t(#Cooper)<>1
ProcedureReturn #True
EndIf
EndProcedure
Procedure C4(Array t(1))
If t(#Miller) >= t(#Cooper)
ProcedureReturn #True
EndIf
EndProcedure
Procedure C5(Array t(1))
If t(#Fletcher)<>1 And t(#Fletcher)<>5
ProcedureReturn #True
EndIf
EndProcedure
Procedure C6(Array t(1))
If Int(Abs(t(#Smith)-t(#Fletcher)))<>1
ProcedureReturn #True
EndIf
EndProcedure
If OpenConsole()
Dim People(4)
Dim Conditions(5)
Define a, b, c, d, e, i
;
;- Load all conditions
Conditions(i)=@C1(): i+1
Conditions(i)=@C2(): i+1
Conditions(i)=@C3(): i+1
Conditions(i)=@C4(): i+1
Conditions(i)=@C5(): i+1
Conditions(i)=@C6()
;
; generate and the all legal combinations
For a=1 To 5
For b=1 To 5
If a=b: Continue: EndIf
For c=1 To 5
If a=c Or b=c: Continue: EndIf
For d=1 To 5
If d=a Or d=b Or d=c : Continue: EndIf
For e=1 To 5
If e=a Or e=b Or e=c Or e=d: Continue: EndIf
People(#Baker)=a
People(#Cooper)=b
People(#Fletcher)=c
People(#Miller)=d
People(#Smith)=e
If checkTenands(People(), Conditions())
PrintN("Solution found;")
PrintN("Baker="+Str(a)+#CRLF$+"Cooper="+Str(b)+#CRLF$+"Fletcher="+Str(c))
PrintN("Miller="+Str(d)+#CRLF$+"Smith="+Str(e)+#CRLF$)
EndIf
Next
Next
Next
Next
Next
Print("Press ENTER to exit"): Input()
EndIf</syntaxhighlight>
<pre>Solution found;
Baker=3
Cooper=2
Fletcher=4
Miller=5
Smith=1</pre>
====Port of [http://rosettacode.org/wiki/Dinesman%27s_multiple-dwelling_problem#C C code solution]====
<syntaxhighlight lang="purebasic">
EnableExplicit
Global verbose = #False
Macro COND ( a, b )
Procedure a ( Array s ( 1 ) )
ProcedureReturn Bool( b )
EndProcedure
EndMacro
Prototype condition ( Array s ( 1 ) )
#N_FLOORS = 5
#TOP = #N_FLOORS - 1
Global Dim solutions ( #N_FLOORS - 1 )
Global Dim occupied ( #N_FLOORS - 1 )
Enumeration tenants
#baker
#cooper
#fletcher
#miller
#smith
#phantom_of_the_opera
EndEnumeration
Global Dim names.s ( 4 )
names( 0 ) = "baker"
names( 1 ) = "cooper"
names( 2 ) = "fletcher"
names( 3 ) = "miller"
names( 4 ) = "smith"
COND( c0, s( #baker ) <> #TOP )
COND( c1, s( #cooper ) <> 0 )
COND( c2, s( #fletcher ) <> 0 And s( #fletcher ) <> #TOP )
COND( c3, s( #miller ) > s( #cooper ) )
COND( c4, Abs( s( #smith ) - s( #fletcher ) ) <> 1 )
COND( c5, Abs( s( #cooper ) - s( #fletcher ) ) <> 1 )
#N_CONDITIONS = 6
Global Dim conds ( #N_CONDITIONS - 1 )
conds( 0 ) = @c0()
conds( 1 ) = @c1()
conds( 2 ) = @c2()
conds( 3 ) = @c3()
conds( 4 ) = @c4()
conds( 5 ) = @c5()
Procedure solve ( person.i )
Protected i.i, j.i
If person = #phantom_of_the_opera
For i = 0 To #N_CONDITIONS - 1
Protected proc.condition = conds( i )
If proc( solutions( ) )
Continue
EndIf
If verbose
For j = 0 To #N_FLOORS - 1
PrintN( Str( solutions( j ) ) + " " + names( j ) )
Next
PrintN( "cond" + Str( i ) + " bad\n" )
EndIf
ProcedureReturn 0
Next
PrintN( "Found arrangement:" )
For i = 0 To #N_FLOORS - 1
PrintN( Str( solutions( i ) ) + " " + names( i ) )
Next
ProcedureReturn 1
EndIf
For i = 0 To #N_FLOORS - 1
If occupied( i )
Continue
EndIf
solutions( person ) = i
occupied( i ) = #True
If solve( person + 1 )
ProcedureReturn #True
EndIf
occupied( i ) = #False
Next
ProcedureReturn #False
EndProcedure
OpenConsole( )
verbose = #False
If Not solve( 0 )
PrintN( "Nobody lives anywhere" )
EndIf
Input( )
CloseConsole( )
End</syntaxhighlight>
<pre>Found arrangement:
2 baker
1 cooper
3 fletcher
4 miller
0 smith</pre>
==={{header|QBasic}}===
{{trans|FreeBASIC}}
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{works with|True BASIC}}
<syntaxhighlight lang="qbasic">PRINT "Los apartamentos están numerados del 0 (bajo) al 4 (ático)."
PRINT "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
PRINT "- Baker no vive en el último apartamento (ático)."
PRINT "- Cooper no vive en el piso inferior (bajo)."
PRINT "- Fletcher no vive ni en el ático ni en el bajo."
PRINT "- Miller vive en un apartamento más alto que Cooper."
PRINT "- Smith no vive en un apartamento adyacente al de Fletcher."
PRINT "- Fletcher no vive en un apartamento adyacente al de Cooper."
PRINT
FOR baker = 0 TO 3
FOR cooper = 1 TO 4
FOR fletcher = 1 TO 3
FOR miller = 0 TO 4
FOR smith = 0 TO 4
IF baker <> cooper AND baker <> fletcher AND baker <> miller AND baker <> smith AND cooper <> fletcher THEN
IF cooper <> miller AND cooper <> smith AND fletcher <> miller AND fletcher <> smith AND miller <> smith THEN
IF miller > cooper AND ABS(smith - fletcher) <> 1 AND ABS(fletcher - cooper) <> 1 THEN
PRINT "Baker vive en el piso "; baker
PRINT "Cooper vive en el piso "; cooper
PRINT "Fletcher vive en el piso "; fletcher
PRINT "Miller vive en el piso "; miller
PRINT "Smith vive en el piso "; smith
END IF
END IF
END IF
NEXT smith
NEXT miller
NEXT fletcher
NEXT cooper
NEXT baker
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
==={{header|Run BASIC}}===
This program simply iterates by looking at each room available for each person.
It then looks to see if it meets the requirements for each person by looking at the results of the iteration.
It makes sure the room numbers add up to 15 which is the requirement of adding the floors in 1 + 2 + 3 + 4 + 5 = 15.
<syntaxhighlight lang="runbasic">for baler = 1 to 4 ' can not be in room 5
for cooper = 2 to 5 ' can not be in room 1
for fletcher = 2 to 4 ' can not be in room 1 or 5
for miller = 1 to 5 ' can be in any room
for smith = 1 to 5 ' can be in any room
if baler <> cooper and fletcher <> miller and miller > cooper and abs(smith - fletcher) > 1 and abs(fletcher - cooper) > 1 then
if baler + cooper + fletcher + miller + smith = 15 then ' that is 1 + 2 + 3 + 4 + 5
rooms$ = baler;cooper;fletcher;miller;smith
print "baler: ";baler;" copper: ";cooper;" fletcher: ";fletcher;" miller: ";miller;" smith: ";smith
end
end if
end if
next smith
next miller
next fletcher
next cooper
next baler
print "Can't assign rooms" ' print this if it can not find a solution</syntaxhighlight>
<pre>baler: 3 copper: 2 fletcher: 4 miller: 5 smith: 1</pre>
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">PRINT "Los apartamentos están numerados del 0 (bajo) al 4 (ático)."
PRINT "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
PRINT "- Baker no vive en el último apartamento (ático)."
PRINT "- Cooper no vive en el piso inferior (bajo)."
PRINT "- Fletcher no vive ni en el ático ni en el bajo."
PRINT "- Miller vive en un apartamento más alto que Cooper."
PRINT "- Smith no vive en un apartamento adyacente al de Fletcher."
PRINT "- Fletcher no vive en un apartamento adyacente al de Cooper."
PRINT
FOR baker = 0 TO 3
FOR cooper = 1 TO 4
FOR fletcher = 1 TO 3
FOR miller = 0 TO 4
FOR smith = 0 TO 4
IF baker <> cooper AND baker <> fletcher AND baker <> miller AND baker <> smith AND cooper <> fletcher THEN
IF cooper <> miller AND cooper <> smith AND fletcher <> miller AND fletcher <> smith AND miller <> smith THEN
IF miller > cooper AND ABS(smith - fletcher) <> 1 AND ABS(fletcher - cooper) <> 1 THEN
PRINT "Baker vive en el piso "; baker
PRINT "Cooper vive en el piso "; cooper
PRINT "Fletcher vive en el piso "; fletcher
PRINT "Miller vive en el piso "; miller
PRINT "Smith vive en el piso "; smith
END IF
END IF
END IF
NEXT smith
NEXT miller
NEXT fletcher
NEXT cooper
NEXT baker
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
==={{header|uBasic/4tH}}===
{{trans|BBC Basic}}
<syntaxhighlight lang="text">REM Floors are numbered 0 (ground) to 4 (top)
FOR B = 0 TO 4
FOR C = 0 TO 4
FOR F = 0 TO 4
FOR M = 0 TO 4
FOR S = 0 TO 4
GOSUB 100 : IF POP() THEN
GOSUB 110 : IF POP() THEN
GOSUB 120 : IF POP() THEN
GOSUB 130 : IF POP() THEN
GOSUB 140 : IF POP() THEN
GOSUB 150 : IF POP() THEN
GOSUB 160 : IF POP() THEN
PRINT "Baker lives on floor " ; B + 1
PRINT "Cooper lives on floor " ; C + 1
PRINT "Fletcher lives on floor " ; F + 1
PRINT "Miller lives on floor " ; M + 1
PRINT "Smith lives on floor " ; S + 1
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
NEXT S
NEXT M
NEXT F
NEXT C
NEXT B
END
REM "Baker, Cooper, Fletcher, Miller, and Smith live on different floors"
100 PUSH (B#C)*(B#F)*(B#M)*(B#S)*(C#F)*(C#M)*(C#S)*(F#M)*(F#S)*(M#S)
RETURN
REM "Baker does not live on the top floor"
110 PUSH B#4
RETURN
REM "Cooper does not live on the bottom floor"
120 PUSH C#0
RETURN
REM "Fletcher does not live on either the top or the bottom floor"
130 PUSH (F#0)*(F#4)
RETURN
REM "Miller lives on a higher floor than does Cooper"
140 PUSH M>C
RETURN
REM "Smith does not live on a floor adjacent to Fletcher's"
150 PUSH ABS(S-F)#1
RETURN
REM "Fletcher does not live on a floor adjacent to Cooper's"
160 PUSH ABS(F-C)#1
RETURN</syntaxhighlight>
Output:
<pre>
Baker lives on floor 3
Cooper lives on floor 2
Fletcher lives on floor 4
Miller lives on floor 5
Smith lives on floor 1
0 OK, 0:1442
</pre>
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">print "Los apartamentos estan numerados del 0 (bajo) al 4 (atico)."
print "Baker, Cooper, Fletcher, Miller y Smith viven en apartamentos diferentes."
print "- Baker no vive en el ultimo apartamento (atico)."
print "- Cooper no vive en el piso inferior (bajo)."
print "- Fletcher no vive ni en el atico ni en el bajo."
print "- Miller vive en un apartamento más alto que Cooper."
print "- Smith no vive en un apartamento adyacente al de Fletcher."
print "- Fletcher no vive en un apartamento adyacente al de Cooper."
print
for Baker = 0 to 3
for Cooper = 1 to 4
for Fletcher = 1 to 3
for Miller = 0 to 4
for Smith = 0 to 4
if Baker<>Cooper and Baker<>Fletcher and Baker<>Miller and Baker<>Smith and Cooper<>Fletcher and Cooper<>Miller and Cooper<>Smith and Fletcher<>Miller and Fletcher<>Smith and Miller<>Smith and Miller>Cooper and abs(Smith-Fletcher)<>1 and abs(Fletcher-Cooper)<>1 then
print "Baker vive en el piso ", Baker
print "Cooper vive en el piso ", Cooper
print "Fletcher vive en el piso ", Fletcher
print "Miller vive en el piso ", Miller
print "Smith vive en el piso ", Smith
end if
next Smith
next Miller
next Fletcher
next Cooper
next Baker
end</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
==={{header|ZX Spectrum Basic}}===
{{trans|BBC_BASIC}}
<syntaxhighlight lang="zxbasic">10 REM Floors are numbered 0 (ground) to 4 (top)
20 REM "Baker, Cooper, Fletcher, Miller, and Smith live on different floors":
30 REM "Baker does not live on the top floor"
40 REM "Cooper does not live on the bottom floor"
50 REM "Fletcher does not live on either the top or the bottom floor"
60 REM "Miller lives on a higher floor than does Cooper"
70 REM "Smith does not live on a floor adjacent to Fletcher's"
80 REM "Fletcher does not live on a floor adjacent to Cooper's"
90 FOR b=0 TO 4: FOR c=0 TO 4: FOR f=0 TO 4: FOR m=0 TO 4: FOR s=0 TO 4
100 IF B<>C AND B<>F AND B<>M AND B<>S AND C<>F AND C<>M AND C<>S AND F<>M AND F<>S AND M<>S AND B<>4 AND C<>0 AND F<>0 AND F<>4 AND M>C AND ABS (S-F)<>1 AND ABS (F-C)<>1 THEN PRINT "Baker lives on floor ";b: PRINT "Cooper lives on floor ";c: PRINT "Fletcher lives on floor ";f: PRINT "Miller lives on floor ";m: PRINT "Smith lives on floor ";s: STOP
110 NEXT s: NEXT m: NEXT f: NEXT c: NEXT b</syntaxhighlight>
=={{header|Bracmat}}==
Line 304 ⟶ 1,016:
If there are no reserved characters in a name, double quotes are optional.
<
& ( constraints
=
Line 330 ⟶ 1,042:
& solution$(.!people)
| { After outputting all solutions, the lhs of the | operator fails. The rhs of the | operator, here an empty string, is the final result. }
);</
<pre>Inhabitants, from bottom to top: Smith Cooper Baker Fletcher Miller</pre>
=={{header|C}}==
<
#include <stdlib.h>
Line 413 ⟶ 1,125:
if (!solve(0)) printf("Nobody lives anywhere\n");
return 0;
}</
{{out}}
<pre>Found arrangement:
Line 429 ⟶ 1,141:
=={{header|C++}}==
{{Works with|C++14}}
<
#include <array>
#include <cmath>
Line 468 ⟶ 1,180:
return EXIT_SUCCESS;
}</
=={{header|C sharp|C#}}==
===Constraints as functions solution===
Usage of the DinesmanSolver is very simple. Just feed it a bunch of constraints in the form of functions. (It could also be one function with a bunch of 'and' clauses)<br/>
Line 477 ⟶ 1,189:
For each solution, it will output an array of integers that represent the tenants ordered by floor number, from the bottom floor to the top.
<
{
public static void Main()
Line 544 ⟶ 1,256:
if (index == position) yield return newElement;
}
}</
{{out}}
<pre>
Line 552 ⟶ 1,264:
This challenge is badly stated. It is trivial to state/add any variant as a where clause (and to the enum) in the Linq query. Need more information in order to automatically parse such statements and there is no specification of this in the challenge.
{{works with|C sharp|C#|7}}
<
using System.Collections.Generic;
using static System.Linq.Enumerable;
Line 590 ⟶ 1,302:
public static IEnumerable<T> ToSingleton<T>(this T item) { yield return item; }
}</
{{out}}
<pre>Smith Cooper Baker Fletcher Miller
Line 596 ⟶ 1,308:
=={{header|Ceylon}}==
<
function notAdjacent(Integer a, Integer b) => (a - b).magnitude >= 2;
Line 619 ⟶ 1,331:
print(solutions.first else "No solution!");
}</
{{out}}
<pre>baker lives on 3
Line 635 ⟶ 1,347:
and additional constraint functions could be defined as necessary.
The final part of the code searches for all solutions and prints them out.
<
(:use [clojure.core.logic]
[clojure.tools.macro :as macro]))
Line 672 ⟶ 1,384:
(println "solution(s) highest to lowest floor:")
(doseq [soln solns] (println " " soln)))
</syntaxhighlight>
{{out}}
<pre>solution count: 1
Line 680 ⟶ 1,392:
=={{header|Common Lisp}}==
This solution uses the [https://www.cliki.net/screamer screamer] package to develop a constraint based solution. Two versions are shown, both produce the same answer. The first solves it by assigning a number to each man, the second by creating a list of all the men. The purpose of showing both solutions is to demonstrate that screamer can be used to solve constraints with various types.
<
(defpackage :dinesman
(:use :cl
Line 724 ⟶ 1,436:
(fail))
(format t "(~{~A~^ ~})~%" building))))
</syntaxhighlight>
=={{header|Crystal}}==
Line 730 ⟶ 1,442:
This example modifies the Enumerable(T) mixin and adds a method index! that requires each index not to be nil.
<
def index!(element)
index(element).not_nil!
Line 747 ⟶ 1,459:
]
puts residents.permutations.find { |p| predicates.all? &.call p }</
=={{header|D}}==
This code uses the second lazy permutations function of '''[[Permutations#Lazy_version]]'''.
As for flexibility: the solve code works with an arbitrary number of people and predicates.
<syntaxhighlight lang="d">
import std.stdio, std.math, std.algorithm, std.traits, std.array, permutations2:permutations;
void main() {
enum Names { Baker, Cooper, Fletcher, Miller, Smith }
immutable(bool function(in Names[]) pure nothrow)[] predicates = [
s => s.countUntil(Names.Fletcher) != 4
];
permutations([EnumMembers!Names]).filter!(solution => predicates.all!(pred => pred(solution)))
.writeln;
}</syntaxhighlight>
{{out}}
<pre>[[
===Simpler Version===
<syntaxhighlight lang="d">
void main() {
import std.stdio, std.math, std.algorithm, permutations2:permutations;
["Baker", "Cooper", "Fletcher", "Miller", "Smith"]
s.countUntil("Baker") != 4 && s.countUntil("Cooper") != 0 &&
s.countUntil("Fletcher") != 0 && s.countUntil("Fletcher") != 4 &&
s.countUntil("Miller") > s.countUntil("Cooper") &&
abs(s.countUntil("Smith") - s.countUntil("Fletcher")) != 1 &&
abs(s.countUntil("Cooper") - s.countUntil("Fletcher")) != 1)
}</
The output is the same.
=={{header|EasyLang}}==
{{trans|11l}}
<syntaxhighlight>
proc nextperm . a[] .
n = len a[]
k = n - 1
while k >= 1 and a[k + 1] <= a[k]
k -= 1
.
if k = 0
a[] = [ ]
return
.
l = n
while a[l] <= a[k]
l -= 1
.
swap a[l] a[k]
k += 1
while k < n
swap a[k] a[n]
k += 1
n -= 1
.
.
for i = 1 to 5
floors[] &= i
.
BAKER = 1
COOPER = 2
FLETCHER = 3
MILLER = 4
SMITH = 5
names$[] = [ "Baker" "Cooper" "Fletcher" "Miller" "Smith" ]
#
repeat
if floors[BAKER] <> 5 and floors[COOPER] <> 1 and floors[FLETCHER] <> 1 and floors[FLETCHER] <> 5
if floors[MILLER] > floors[COOPER] and abs (floors[SMITH] - floors[FLETCHER]) <> 1 and abs (floors[FLETCHER] - floors[COOPER]) <> 1
for i to 5
print names$[i] & " lives on floor " & floors[i]
.
break 1
.
.
nextperm floors[]
until len floors[] = 0
.
</syntaxhighlight>
{{out}}
<pre>
Baker lives on floor 3
Cooper lives on floor 2
Fletcher lives on floor 4
Miller lives on floor 5
Smith lives on floor 1
</pre>
=={{header|EchoLisp}}==
The problem is solved using the '''amb''' library. The solution separates the constrainst procedure from the solver procedure. The solver does not depend on names, number of floors. This flexibility allows to easily add floors, names, constraints. See Antoinette example below, Antoinette is very close ❤️ to Cooper, and wants a prime numbered floor.
===Setup - Solver===
<
(require 'hash)
(require' amb)
Line 828 ⟶ 1,595:
(make-hash)) ;; hash table : "name" -> floor
)
</syntaxhighlight>
=== Problem data - constraints ===
<
(define names '("baker" "cooper" "fletcher" "miller" "smith" ))
Line 852 ⟶ 1,619:
(amb-require (not (touch "fletcher" "cooper")))
)
</syntaxhighlight>
{{out}}
<
(task names)
→ ((baker . 2) (cooper . 1) (fletcher . 3) (miller . 4) (smith . 0))
</syntaxhighlight>
=== Changing data - constraints ===
<
;; add a name/floor
(define names '("baker" "cooper" "fletcher" "miller" "smith" "antoinette"))
Line 874 ⟶ 1,641:
)
</syntaxhighlight>
{{out}}
<
(task names)
→ ((baker . 0) (cooper . 1) (fletcher . 3) (miller . 4) (smith . 5) (antoinette . 2))
</syntaxhighlight>
=={{header|Elixir}}==
{{trans|Ruby}}
'''Simple solution:'''
<
def problem do
names = ~w( Baker Cooper Fletcher Miller Smith )a
Line 910 ⟶ 1,677:
end
Dinesman.problem</
{{out}}
Line 927 ⟶ 1,694:
The design of the rules can be argued.
Perhaps {cooper, does_not_live_on, 0}, etc, would be better for people unfamiliar with lisp.
<syntaxhighlight lang="erlang">
-module( dinesman_multiple_dwelling ).
Line 971 ⟶ 1,738:
rules_fun( {not_below, Person1, Person2} ) -> fun (House) -> is_not_below( Person1, Person2, House ) end;
rules_fun( {not_adjacent, Person1, Person2} ) -> fun (House) -> is_not_adjacent( Person1, Person2, House ) end.
</syntaxhighlight>
{{out}}
<pre>
Line 983 ⟶ 1,750:
=={{header|ERRE}}==
<
BEGIN
Line 1,030 ⟶ 1,797:
END FOR ! Cooper
END FOR ! Baker
END PROGRAM</
{{out}}
<pre>
Line 1,040 ⟶ 1,807:
</pre>
=={{header|F_Sharp|F#}}==
This task uses [[Permutations_by_swapping#F.23]]
<syntaxhighlight lang="fsharp">
// Dinesman's multiple-dwelling. Nigel Galloway: September 23rd., 2020
type names = |Baker=0 |Cooper=1 |Miller=2 |Smith=3 |Fletcher=4
let fN=Ring.PlainChanges [|for n in System.Enum.GetValues(typeof<names>)->n:?>names|]
let fG n g l=n|>Array.pairwise|>Array.forall(fun n->match n with (n,i) when (n=g && i=l)->false |(i,n) when (n=g && i=l)->false |_->true)
fN|>Seq.filter(fun n->n.[4]<>names.Baker && n.[0]<>names.Cooper && n.[0]<>names.Fletcher && n.[4]<>names.Fletcher && fG n names.Smith names.Fletcher
&& fG n names.Cooper names.Fletcher && (Array.findIndex((=)names.Cooper) n) < (Array.findIndex((=)names.Miller) n))
|>Seq.iter(Array.iteri(fun n g->printfn "%A lives on floor %d" g n))
</syntaxhighlight>
{{out}}
<pre>
Smith lives on floor 0
Cooper lives on floor 1
Baker lives on floor 2
Fletcher lives on floor 3
Miller lives on floor 4
</pre>
=={{header|Factor}}==
All rules are encoded in the ``meets-constraints?`` word. Any variations to the rules requires modifying ``meets-constraints?``
<
combinators.short-circuit
math math.combinatorics math.ranges
Line 1,069 ⟶ 1,855:
: dinesman ( -- )
solutions [ >names . ] each ;</
{{out}}
<pre>{
Line 1,088 ⟶ 1,874:
Although this is not ANS Forth, one should have little trouble converting it.
{{works with|4tH|3.6.20}}
<
enum cooper
enum fletcher
Line 1,138 ⟶ 1,924:
; \ show the solution
dinesman</
{{out}}
<pre>
Line 1,149 ⟶ 1,935:
=={{header|Go}}==
<
import "fmt"
Line 1,270 ⟶ 2,056:
fmt.Println(t, f)
}
}</
{{out}}
<pre>
Line 1,283 ⟶ 2,069:
The List monad is perfect for this kind of problem. One can express the problem statements in a very natural and concise way:
{{works with|GHC|6.10+}}
<
import Control.Monad (guard)
Line 1,319 ⟶ 2,105:
main = do
print $ head dinesman -- print first solution: (3,2,4,5,1)
print dinesman -- print all solutions (only one): [(3,2,4,5,1)]</
Or as a list comprehension (syntactic sugar for a list monad):
<
main :: IO ()
main =
print
[ ( "Baker lives on "
)
| [b, c, f, m, s] <- permutations [1 .. 5],
abs (c - f) > 1
]</syntaxhighlight>
{{out}}
<pre>[("Baker lives on 3","Cooper lives on 2","Fletcher lives on 4","Miller lives on 5","Smith lives on 1")]</pre>
Line 1,348 ⟶ 2,136:
The rules explicitly call stop() after showing the solution. Removing the ''stop'' would cause the solver to try all possible cases and report all possible solutions (if there were multiple ones).
<
global nameL, nameT, rules
Line 1,418 ⟶ 2,206:
procedure top() # return top
return *nameL
end</
{{out}}
Line 1,427 ⟶ 2,215:
Miller lives in 5
Smith lives in 1</pre>
=={{header|J}}==
Line 1,454 ⟶ 2,221:
We can represent these possibilities as permutations of the residents' initials, arranged in order from lowest floor to top floor:
<
Additionally, we are given a variety of constraints which eliminate some possibilities:
<
possible=: (#~ 'C' ~: {."1) possible NB. Cooper not on bottom floor
possible=: (#~ 'F' ~: {:"1) possible NB. Fletcher not on top floor
Line 1,466 ⟶ 2,233:
possible=: (#~ 0 = +/@E."1~&'FS') possible NB. Fletcher not immediately below Smith
possible=: (#~ 0 = +/@E."1~&'CF') possible NB. Cooper not immediately below Fletcher
possible=: (#~ 0 = +/@E."1~&'FC') possible NB. Fletcher not immediately below Cooper</
The answer is thus:
<
SCBFM</
(bottom floor) Smith, Cooper, Baker, Fletcher, Miller (top floor)
Line 1,478 ⟶ 2,245:
'''Code:'''
<
class DinesmanMultipleDwelling {
Line 1,564 ⟶ 2,331:
}
}
</syntaxhighlight>
{{out}}
Line 1,581 ⟶ 2,348:
The predicates here can be varied, and the depth of concatMap nestings can be adjusted to match the number of unknowns in play, with each concatMap binding one name, and defining the list of its possible values.
<
'use strict';
Line 1,634 ⟶ 2,401:
// --> [{"Baker":3, "Cooper":2, "Fletcher":4, "Miller":5, "Smith":1}]
})();</
{{Out}}
<
====Less flexibility====
Line 1,648 ⟶ 2,415:
ES6 splat assignment allows us to bind all five names in a single application of concatMap. We now also need a '''permutations''' function of some kind.
<
'use strict';
Line 1,703 ⟶ 2,470:
// --> [{"Baker":3, "Cooper":2, "Fletcher":4, "Miller":5, "Smith":1}]
})();
</syntaxhighlight>
<
=={{header|jq}}==
Line 1,714 ⟶ 2,481:
The solution presented here does not blindly generate all permutations. It can be characterized as a constraint-oriented approach.
<
# particular position signifying that the identity of the occupant
# there has not yet been determined.
Line 1,729 ⟶ 2,496:
def bottom: 0;
def higher(j): . > j;
def adjacent(j): (. - j) | (. == 1 or . == -1);</
'''Solution''':
<
| resides("Baker"; . != top) # Baker does not live on the top floor
| resides("Cooper"; . != bottom) # Cooper does not live on the bottom floor
Line 1,739 ⟶ 2,506:
| index("Fletcher") as $Fletcher
| resides("Smith"; adjacent($Fletcher) | not) # Smith does not live on a floor adjacent to Fletcher's.
| select( $Fletcher | adjacent( $Cooper ) | not ) # Fletcher does not live on a floor adjacent to Cooper's.</
'''Out''':
<syntaxhighlight lang="sh">
$ jq -n -f Dinesman.jq
[
Line 1,749 ⟶ 2,516:
"Fletcher",
"Miller"
]</
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
function solve(n::Vector{<:AbstractString}, pred::Vector{<:Function})
Line 1,776 ⟶ 2,543:
solutions = solve(Names, predicates)
foreach(x -> println(join(x, ", ")), solutions)</
{{out}}
Line 1,784 ⟶ 2,551:
Tested with Kona.
<syntaxhighlight lang="k">
perm: {x@m@&n=(#?:)'m:!n#n:#x}
filter: {y[& x'y]}
Line 1,797 ⟶ 2,564:
p: reject[{adjacent[`Cooper; `Fletcher; x]}; p]
p: reject[{(x ? `Fletcher)_in (0 4)}; p]
</syntaxhighlight>
Output:
<pre>
Line 1,804 ⟶ 2,571:
=={{header|Kotlin}}==
<
typealias Predicate = (List<String>) -> Boolean
Line 1,853 ⟶ 2,620:
}
}
}</
{{out}}
Line 1,867 ⟶ 2,634:
=={{header|Lua}}==
<
local function perm(n)
local r = {}
Line 1,929 ⟶ 2,696:
end
print(solve (conds, tenants))</
{{Output}}
<pre> Baker lives on floor 3
Line 1,936 ⟶ 2,703:
Miller lives on floor 5
Smith lives on floor 1</pre>
=={{header|M2000 Interpreter}}==
===== Using Permutation Step Function =====
<syntaxhighlight lang="m2000 interpreter">
Module Dinesman_s_multiple_dwelling_problem {
// this is the standard perimutation function
// which create a lambda function:
// pointer_to_array=Func(&BooleanVariable)
// when BooleanVariable = true we get the last permutation
Function PermutationStep (a as array) {
c1=lambda (&f, a) ->{
=a : f=true
}
integer m=len(a)
if m=0 then Error "No items to make permutations"
c=c1
While m>1
c1=lambda c2=c,p=0%, m=(,) (&f, a, clear as boolean=false) ->{
if clear then m=(,)
if len(m)=0 then m=a
=cons(car(m),c2(&f, cdr(m)))
if f then f=false:p++: m=cons(cdr(m), car(m)) : if p=len(m) then p=0 : m=(,):: f=true
}
c=c1
m--
End While
=lambda c, a (&f, clear as boolean=false) -> {
=c(&f, a, clear)
}
}
boolean k
object s=("Baker", "Cooper", "Fletcher", "Miller", "Smith")
StepA=PermutationStep(s)
while not k
s=StepA(&k)
if s#val$(4)= "Baker" then continue
if s#val$(0)="Cooper" then continue
if s#val$(0)="Fletcher" then continue
if s#val$(4)="Fletcher" then continue
if s#pos("Cooper")> s#pos("Miller") then continue
if abs(s#pos("Smith")-s#pos("Fletcher"))=1 then continue
if abs(s#pos("Cooper")-s#pos("Fletcher"))=1 then continue
exit // for one solution
end while
object c=each(s)
while c
Print array$(c)+" lives on floor "+(c^+1)
end while
}
Dinesman_s_multiple_dwelling_problem
</syntaxhighlight>
{{out}}
<pre>
Smith lives on floor 1
Cooper lives on floor 2
Baker lives on floor 3
Fletcher lives on floor 4
Miller lives on floor 5
</pre>
===== Using Amp function =====
<syntaxhighlight lang="m2000 interpreter">
Module Using_AmbFunction {
Enum Solution {First, Any=-1}
Function Amb(way as Solution, failure) {
read a
c1=lambda i=0, a, (&any, &ret) ->{
any=(array(a,i),)
ret=any
i++
ok=i=len(a)
if ok then i=0
=ok
}
m=stack.size
if m=0 then Error "At least two arrays needed"
c=c1
while m>0 {
read a
c1=lambda c2=c, i=0, a, (&any, &ret) ->{
any=(array(a,i),)
ret=(,) : ok=false : anyother=(,)
ok=c2(&anyother, &ret)
ret=cons(ret, any)
if ok then i++
ok=i=len(a)
if ok then i=0
=ok
}
c=c1 : m--
}
ok=false
any=(,)
flush
while not ok
ret=(,)
ok=c(&any, &ret)
s=stack(ret)
if not failure(! s) then data ret : if way>0 then ok=true
End While
if empty then
ret=(("",),)
else
ret=array([])
end if
=ret
}
Range=lambda (a, f) ->{
for i=a to f-1: data i: next
=array([])
}
Baker=range(1, 5)
Cooper=range(2, 6)
Fletcher=range(2, 5)
Miller=range(1,6)
Smith=range(1,6)
failure=lambda (Baker, Cooper, Fletcher, Miller, Smith)->{
if Baker=Cooper or Baker=Fletcher or Baker=Miller or Baker=Smith then =true:exit
if Cooper=Fletcher or Cooper =Miller or Cooper=Smith then =true:exit
if Fletcher=Miller or Fletcher=Smith or Miller=Smith then =true:exit
if Miller<Cooper or abs(Cooper-Fletcher)=1 or abs(Smith-Fletcher)=1 then =true:exit
}
all=amb(Any, failure, Baker, Cooper, Fletcher, Miller, Smith)
k=each(all)
s=("Baker", "Cooper", "Fletcher", "Miller", "Smith")
while k
z=array(k)
zz=each(z, , -2)
while zz
? s#val$(zz^)+" ("+array(zz)+"), ";
end while
zz=each(z, -1)
while zz
? s#val$(zz^)+" ("+array(zz)+") "
end while
end while
}
Using_AmbFunction
</syntaxhighlight>
{{out}}
<pre>
Baker (3), Cooper (2), Fletcher (4), Miller (5), Smith (1)
</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Loads all names into memory as variables, then asserts various restrictions on them before trying to resolve them by assuming that they're integers. This works by assuming that the names are the floors the people are on. This method is slow but direct.
<syntaxhighlight lang="mathematica">
{Baker, Cooper, Fletcher, Miller, Smith};
(Unequal @@ %) && (And @@ (0 < # < 6 & /@ %)) &&
Line 1,949 ⟶ 2,862:
Abs[Cooper - Fletcher] > 1 //
Reduce[#, %, Integers] &
</syntaxhighlight>
{{out}}
<
===Alternate Version===
A much quicker and traditional method. This generates all permutations of a list containing the five names as strings. The list of permutations is then filtered using the restrictions given in the problem until only one permutation is left.
<syntaxhighlight lang="mathematica">
p = Position[#1, #2][[1, 1]] &;
Permutations[{"Baker", "Cooper", "Fletcher", "Miller", "Smith"}, {5}];
Line 1,965 ⟶ 2,878:
Select[%, Abs[#~p~"Smith" - #~p~"Fletcher"] > 1 &];
Select[%, Abs[#~p~"Cooper" - #~p~"Fletcher"] > 1 &]
</syntaxhighlight>
{{out}}
<
=={{header|MiniZinc}}==
<syntaxhighlight lang="minizinc">
%Dinesman's multiple-dwelling problem. Nigel Galloway, September 25th., 2020
include "alldifferent.mzn";
enum names={Baker,Cooper,Miller,Smith,Fletcher};
array[names] of var 1..5: res; constraint alldifferent([res[n] | n in names]);
constraint res[Baker] !=5;
constraint res[Cooper] !=1;
constraint res[Fletcher] !=1;
constraint res[Fletcher] !=5;
constraint abs(res[Smith] -res[Fletcher]) > 1;
constraint abs(res[Cooper]-res[Fletcher]) > 1;
constraint res[Cooper] < res[Miller];
output["\(n) resides on floor \(res[n])\n" | n in names]
</syntaxhighlight>
{{out}}
<pre>
Baker resides on floor 3
Cooper resides on floor 2
Miller resides on floor 5
Smith resides on floor 1
Fletcher resides on floor 4
</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm
type
Person {.pure.} = enum Baker, Cooper, Fletcher, Miller, Smith
Floor = range[1..5]
var floors: array[Person, Floor] = [Floor 1, 2, 3, 4, 5]
while true:
if floors[Baker] != 5 and
floors[Cooper] != 1 and
floors[Fletcher] notin [1, 5] and
floors[Miller] > floors[Cooper] and
abs(floors[Smith] - floors[Fletcher]) != 1 and
abs(floors[Fletcher] - floors[Cooper]) != 1:
for person, floor in floors:
echo person, " lives on floor ", floor
break
if not floors.nextPermutation():
echo "No solution found."
break</syntaxhighlight>
{{out}}
<pre>Baker lives on floor 3
Cooper lives on floor 2
Fletcher lives on floor 4
Miller lives on floor 5
Smith lives on floor 1</pre>
=={{header|Perl}}==
Line 1,976 ⟶ 2,944:
'''Setup'''
<
use warnings;
use feature
use List::Util 1.33 qw(pairmap);
use Algorithm::Permute qw(permute);
Line 2,017 ⟶ 2,985:
my $pred = $predicates{$+{pred}};
{ no warnings;
my $expr = '(' .
$
$expr = '!' . $expr if $+{not};
push @expressions, $expr;
}
}
my @f = 1..$i;
eval '
permute {
say join(", ", pairmap { "$f[$b] $a" } %ids)
if ('.join(' && ', @expressions).');
} @f;';
}</
Note that it can easily be extended by modifying the <code>%predicates</code> and <code>%nouns</code> hashes at the top.
Line 2,053 ⟶ 3,022:
Thus, the problem statement from the task description translates to:
<
__DATA__
Line 2,062 ⟶ 3,031:
Miller higher than Cooper
Smith not adjacent to Fletcher
Fletcher not adjacent to Cooper</
{{out}}
Line 2,074 ⟶ 3,043:
=={{header|Phix}}==
Simple static/hard-coded solution (brute force search)
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">Baker</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Cooper</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Fletcher</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Miller</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Smith</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">names</span><span style="color: #0000FF;">={</span><span style="color: #008000;">"Baker"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Cooper"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Miller"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Smith"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Baker</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">5</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Cooper</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Fletcher</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Miller</span><span style="color: #0000FF;">]></span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Cooper</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">and</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Smith</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Fletcher</span><span style="color: #0000FF;">])!=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">and</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Fletcher</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Cooper</span><span style="color: #0000FF;">])!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">names</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,103 ⟶ 3,075:
Something more flexible. The nested rules worked just as well, and
of course the code will cope with various content in names/rules.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">names</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Baker"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Cooper"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Miller"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Smith"</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">rules</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"!="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Baker"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">)},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"!="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Cooper"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"!="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"!="</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">)},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">">"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Miller"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Cooper"</span><span style="color: #0000FF;">},</span>
<span style="color: #000080;font-style:italic;">-- {"!=",{"abs","
<span style="color: #0000FF;">{</span><span style="color: #008000;">"nadj"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Smith"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">},</span>
<span style="color: #000080;font-style:italic;">-- {"!=",{"abs","Fletcher","Cooper"},1},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"nadj"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Fletcher"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Cooper"</span><span style="color: #0000FF;">}}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">rule</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">string</span> <span style="color: #000000;">operand</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">op1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">op2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rule</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">op1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">names</span><span style="color: #0000FF;">)]</span>
<span style="color: #000080;font-style:italic;">-- elsif sequence(op1) then
-- op1 = eval(op1,flats)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">op2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">names</span><span style="color: #0000FF;">)]</span>
<span style="color: #000080;font-style:italic;">-- elsif sequence(op2) then
-- op2 = eval(op2,flats)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">operand</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">"!="</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">op1</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">op2</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">">"</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #000000;">op1</span><span style="color: #0000FF;">></span><span style="color: #000000;">op2</span>
<span style="color: #000080;font-style:italic;">-- case "abs": return abs(op1-op2)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">"nadj"</span><span style="color: #0000FF;">:</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">op2</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">flats</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rules</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">evaluate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rules</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">names</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">names</span><span style="color: #0000FF;">))))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
Same output
=={{header|Picat}}==
===Constraint modelling===
<syntaxhighlight lang="picat">import util.
import cp.
dinesman_cp =>
println(dinesman_cp),
N = 5,
X = [Baker, Cooper, Fletcher, Miller, Smith],
X :: 1..N,
all_different(X),
% Baker does not live on the fifth floor.
Baker #!= 5,
% Cooper does not live on the first floor.
Cooper #!= 1,
% Fletcher does not live on either the fifth or the first floor.
Fletcher #!= 5,
Fletcher #!= 1,
% Miller lives on a higher floor than does Cooper.
Miller #> Cooper,
% Smith does not live on a floor adjacent to Fletcher'.
abs(Smith-Fletcher) #> 1,
% Fletcher does not live on a floor adjacent to Cooper's.
abs(Fletcher-Cooper) #> 1,
solve(X),
println([baker=Baker, cooper=Cooper, fletcher=Fletcher, miller=Miller, smith=Smith]).</syntaxhighlight>
{{out}}
<pre>[baker = 3,cooper = 2,fletcher = 4,miller = 5,smith = 1]</pre>
===Using permutations===
<syntaxhighlight lang="picat">%
% floors: 1: bottom .. 5: top floor
%
constraints([B,C,F,M,S]) =>
B != 5, % Baker not top floor
C != 1, % Cooper not bottom floor
F != 1, F != 5, % Fletcher not botton nor top floor
M > C, % Miller higher floor than Cooper
not adjacent(S, F), % Smith and Fletcher not adjacent
not adjacent(F, C). % Fletcher and Cooper not adjacent
adjacent(A,B) => abs(A-B) == 1.
dinesman2 =>
println(dinesman2),
foreach([B,C,F,M,S] in permutations(1..5), constraints([B,C,F,M,S]))
println([baker=B, cooper=C, fletcher=F, miller=M, smith=S])
end.
</syntaxhighlight>
{{out}}
<pre>[baker = 3,cooper = 2,fletcher = 4,miller = 5,smith = 1]</pre>
=={{header|PicoLisp}}==
Using Pilog (PicoLisp Prolog). The problem can be modified by changing just the 'dwelling' rule (the "Problem statement"). This might involve the names and number of dwellers (the list in the first line), and statements about who does (or does not) live on the top floor (using the 'topFloor' predicate), the bottom floor (using the 'bottomFloor' predicate), on a higher floor (using the 'higherFloor' predicate) or on an adjacent floor (using the 'adjacentFloor' predicate). The logic follows an implied AND, and statements may be arbitrarily combined using OR and NOT (using the 'or' and 'not' predicates), or any other Pilog (Prolog in picoLisp) built-in predicates. If the problem statement has several solutions, they will be all generated.
<
(be dwelling (@Tenants)
(permute (Baker Cooper Fletcher Miller Smith) @Tenants)
Line 2,177 ⟶ 3,215:
(or
((equal (@Tenant1 @Tenant2 . @) @Rest))
((equal (@Tenant2 @Tenant1 . @) @Rest)) ) )</
{{out}}
<pre>: (? (dwelling @Result))
Line 2,185 ⟶ 3,223:
=={{header|PowerShell}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="powershell">
# Floors are numbered 1 (ground) to 5 (top)
Line 2,254 ⟶ 3,292:
}
}
</syntaxhighlight>
The solution sorted by name:
<syntaxhighlight lang="powershell">
$multipleDwellings
</syntaxhighlight>
{{Out}}
<pre>
Line 2,270 ⟶ 3,308:
</pre>
The solution sorted by floor:
<syntaxhighlight lang="powershell">
$multipleDwellings | Sort-Object -Property Floor -Descending
</syntaxhighlight>
{{Out}}
<pre>
Line 2,289 ⟶ 3,327:
Works with SWI-Prolog and library(clpfd) written by '''Markus Triska'''.
<
:- dynamic top/1, bottom/1.
Line 2,371 ⟶ 3,409:
solve(L),
maplist(writeln, L).
</syntaxhighlight>
{{out}}
Line 2,392 ⟶ 3,430:
===Plain Prolog version===
<
select([],_).
Line 2,425 ⟶ 3,463:
-> maplist( writeln, L), nl, write('No more solutions.')
; write('No solutions.').
</syntaxhighlight>
Ease of change (flexibility) is arguably evident in the code. [http://ideone.com/8n9IQ The output]:
Line 2,435 ⟶ 3,473:
===Testing as soon as possible===
<
%% 1. Baker, Cooper, Fletcher, Miller, and Smith live on different floors
%% of an apartment house that contains only five floors.
Line 2,461 ⟶ 3,499:
X = ['Baker'(Baker), 'Cooper'(Cooper), 'Fletcher'(Fletcher),
'Miller'(Miller), 'Smith'(Smith)].
</syntaxhighlight>
[http://ideone.com/1vYTV Running it] produces the same output, but more efficiently. Separate testing in SWI shows 1,328 inferences for the former, 379 inferences for the latter version. Moving rule 7. up below rule 4. brings it down to 295 inferences.
=={{header|Python}}==
Line 2,692 ⟶ 3,511:
Parsing is done with the aid of the multi-line regular expression at the head of the program.
<
from itertools import product
Line 2,823 ⟶ 3,642:
groupname, txt = [(k,v) for k,v in x.groupdict().items() if v][0]
#print ("%r, %r" % (groupname, txt))
handler[groupname](txt)</
;Problem statement
This is not much more than calling a function on the text of the problem!
<
parse_and_solve("""
Baker, Cooper, Fletcher, Miller, and Smith
Line 2,849 ⟶ 3,668:
floor than does Cooper. Smith does not live on a floor
adjacent to Fletcher's. Fletcher does not live on a floor
adjacent to Cooper's. Where does everyone live?""")</
;Output
Line 2,885 ⟶ 3,704:
adjacent to Cooper's. Where does everyone live</pre>
<
if __name__ == '__main__':
Line 2,942 ⟶ 3,761:
print 'No solution found.'
print
</syntaxhighlight>
{{out}}
Line 2,963 ⟶ 3,782:
===Simple Solutions===
<
class Names:
Line 2,980 ⟶ 3,799:
for sol in permutations(Names.seq):
if all(p(sol) for p in predicates):
print(" ".join(x for x, y in sorted(zip(Names.strings, sol), key=lambda x: x[1])))</
{{out}}
<pre>Smith Cooper Baker Fletcher Miller</pre>
Line 2,988 ⟶ 3,807:
{{Trans|Haskell}}
{{Works with|Python|3.7}}
<
from itertools import permutations
Line 3,009 ⟶ 3,828:
1 < abs(c - f)
])
])</
{{Out}}
<pre>[('Baker on 3', 'Cooper on 2', 'Fletcher on 4', 'Miller on 5', 'Smith on 1')]</pre>
Line 3,016 ⟶ 3,835:
Which we could then disaggregate and comment a little more fully, replacing the list comprehension with a direct use of the list monad bind operator (concatMap):
<
from itertools import chain, permutations
Line 3,076 ⟶ 3,895:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>Baker in 3, Cooper in 2, Fletcher in 4, Miller in 5, Smith in 1.</pre>
Line 3,082 ⟶ 3,901:
=={{header|R}}==
<syntaxhighlight lang="r">
names = unlist(strsplit("baker cooper fletcher miller smith", " "))
Line 3,099 ⟶ 3,918:
if (0 == length(seq)) func(built)
else for (x in seq) do.perms( seq[!seq==x], func, c(x, built)) }
</syntaxhighlight>
Testing:
<syntaxhighlight lang="r">
> do.perms(names, test)
From bottom to top: --> smith cooper baker fletcher miller
Line 3,111 ⟶ 3,930:
user system elapsed
0 0 0
</syntaxhighlight>
=={{header|Racket}}==
Line 3,117 ⟶ 3,936:
This is a direct translation of the problem constraints using an <tt>amb</tt> operator to make the choices (and therefore continuations to do the search). Since it's a direct translation, pretty much all aspects of the problem can change. Note that a direct translation was preferred even though it could be made to run much faster.
<
#lang racket
Line 3,161 ⟶ 3,980:
(printf "Solution:\n")
(for ([x (sort residents > #:key car)]) (apply printf " ~a. ~a\n" x)))
</syntaxhighlight>
{{out}}
Line 3,179 ⟶ 3,998:
{{trans|Perl}}
<syntaxhighlight lang="raku"
sub parse_and_solve ($text) {
Line 3,220 ⟶ 4,039:
Smith not adjacent to Fletcher
Fletcher not adjacent to Cooper
END</
Supports the same grammar for the problem statement, as the Perl solution.
Line 3,231 ⟶ 4,050:
===Simple solution===
{{Works with|rakudo|2015-11-15}}
<syntaxhighlight lang="raku"
for (flat (1..5).permutations) -> $b, $c, $f, $m, $s {
say "Baker=$b Cooper=$c Fletcher=$f Miller=$m Smith=$s"
Line 3,241 ⟶ 4,060:
and $f != $c-1|$c+1 # Fletcher !live adjacent to Cooper
;
}</
Adding more people and floors requires changing the list that's being used for the permutations, adding a variable for the new person, a piece of output in the string and finally to adjust all mentions of the "top" floor.
Line 3,273 ⟶ 4,092:
The "rules" that contain '''==''' could be simplified to '''=''' for readability.
<
names= 'Baker Cooper Fletcher Miller Smith' /*names of multiple─dwelling tenants. */
#tenants= words(names) /*the number of tenants in the building*/
floors= 5; top= floors; bottom= 1
say 'found '
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
set: do p=1 for #tenants; call value word(names, p), @.p; end; return
s: if arg(1)=1 then return ''; return "s" /*a simple pluralizer function.*/
th: arg x; x=abs(x); return word('th st nd rd', 1 +x// 10* (x//100%10\==1)*(x//10<4))
Line 3,309 ⟶ 4,128:
if Smith == Fletcher - 1 | Smith == Fletcher + 1 then return
if Fletcher == Cooper - 1 | Fletcher == Cooper + 1 then return
say; do p=1 for #tenants; tenant= word(names, p)
say right(tenant, 35) 'lives on the' @.p || th(@.p) "floor."
end /*p*/ /* [↑] "||" is REXX's concatenation. */
return /* [↑] show tenants in order in NAMES.*/</
{{out|output|text= when using the internal default values and definitions:}}
<pre>
Line 3,325 ⟶ 4,144:
=={{header|Ring}}==
<
floor1 = "return baker!=cooper and baker!=fletcher and baker!=miller and
baker!=smith and cooper!=fletcher and cooper!=miller and
Line 3,354 ⟶ 4,173:
next
next
</syntaxhighlight>
Output:
<pre>
Line 3,367 ⟶ 4,186:
===By parsing the problem===
Inspired by the Python version.
<
lines = problem.split(".")
names = lines.first.scan( /[A-Z]\w*/ )
Line 3,393 ⟶ 4,212:
names.permutation.detect{|candidate| predicates.all?{|predicate| predicate.(candidate)}}
end</
The program operates under these assumptions:
Line 3,402 ⟶ 4,221:
Program invocation:
<
#The relative positional words higher, lower and adjacent can be combined; they need two names, not positions.
Line 3,427 ⟶ 4,246:
adjacent to Cooper's. Where does everyone live?"
[demo1, demo2, problem1, problem2].each{|problem| puts solve( problem ) ;puts }</
{{Output}}
<pre>
Line 3,456 ⟶ 4,275:
===Simple solution===
{{Trans|D}}
<
predicates = [->(c){ :Baker != c.last },
Line 3,465 ⟶ 4,284:
->(c){ (c.index(:Cooper) - c.index(:Fletcher)).abs != 1 }]
puts names.permutation.detect{|candidate| predicates.all?{|predicate| predicate.call(candidate)}}</
{{Output}}
<pre>
Line 3,476 ⟶ 4,295:
===Using grep===
<
N = %w(Baker Cooper Fletcher Miller Smith)
b,c,f,m,s = N
Line 3,488 ⟶ 4,307:
(?=.*(#{f}..+#{c}|#{c}..+#{f}))/x).
first
</syntaxhighlight>
<pre>
"Smith Cooper Baker Fletcher Miller"
</pre>
=={{header|
<syntaxhighlight lang = "rust">use itertools::Itertools;
fn main() {
for p in (1..6).permutations(5) {
let baker: i32 = p[0];
let cooper: i32 = p[1];
let fletcher: i32 = p[2];
(smith - fletcher).abs() > 1 && (cooper - fletcher).abs() > 1 {
print!("Baker on {baker}, Cooper on {cooper}, ");
println!("Fletcher on {fletcher}, Miller on {miller}, Smith on {smith}.");
}
}
</syntaxhighlight>{{out}}
<pre>
Baker on 3, Cooper on 2, Fletcher on 4, Miller on 5, Smith on 1.
</pre>
=={{header|Scala}}==
<
object Dinesman3 extends App {
Line 3,545 ⟶ 4,363:
}
}
}</
{{out}}
Solutions: 1
Line 3,556 ⟶ 4,374:
===Extended task===
We can extend this problem by adding a tenant resp. adding conditions:
<
object Dinesman3 extends App {
Line 3,586 ⟶ 4,404:
}
}
}</
{{out}}
Solutions: 1
Line 3,598 ⟶ 4,416:
===Enhanced Solution ===
Combine the rules with the person names and separated the original task with an extension.
<
object Dinesman2 extends App {
Line 3,644 ⟶ 4,462:
}
}
}</
=={{header|Sidef}}==
===By parsing the problem===
{{trans|Ruby}}
<
var lines = problem.split('.')
var names = lines.first.scan(/\b[A-Z]\w*/)
Line 3,660 ⟶ 4,478:
# Build an array of lambda's
var predicates = lines.
var keywords = line.scan(re_keywords)
var (name1, name2) = line.scan(re_names)...
Line 3,682 ⟶ 4,500:
predicates.all { |predicate| predicate(candidate) } && return candidate
}
}</
Function invocation:
<
David Abe adjacent. David adjacent Ben. Last line."
Line 3,706 ⟶ 4,524:
adjacent to Cooper's. Where does everyone live?"
[demo1, demo2, problem1, problem2].each{|problem| say dinesman(problem).join("\n"); say '' }</
{{out}}
<pre>
Line 3,735 ⟶ 4,553:
===Simple solution===
{{trans|Ruby}}
<
var predicates = [
Line 3,751 ⟶ 4,569:
break
}
}</
{{out}}
<pre>
Line 3,759 ⟶ 4,577:
Fletcher
Miller
</pre>
=={{header|Tailspin}}==
===Simple solution===
<syntaxhighlight lang="tailspin">
templates permutations
when <=1> do [1] !
otherwise
def n: $;
templates expand
def p: $;
1..$n -> \(def k: $;
[$p(1..$k-1)..., $n, $p($k..last)...] !\) !
end expand
$n - 1 -> permutations -> expand !
end permutations
templates index&{of:}
$ -> \[i](<=$of> $i! \) ...!
end index
def names: ['Baker', 'Cooper', 'Fletcher', 'Miller', 'Smith'];
5 -> permutations -> $names($)
-> \(<?($ -> index&{of: 'Baker'} <~=5>)> $! \)
-> \(<?($ -> index&{of: 'Cooper'} <~=1>)> $! \)
-> \(<?($ -> index&{of: 'Fletcher'} <~=1|=5>)> $! \)
-> \(<?($ -> index&{of: 'Cooper'} <..($ -> index&{of:'Miller'})>)> $! \)
-> \(<?(($ -> index&{of: 'Smith'}) - ($ -> index&{of:'Fletcher'}) <~=1|=-1>)> $! \)
-> \(<?(($ -> index&{of: 'Cooper'}) - ($ -> index&{of:'Fletcher'}) <~=1|=-1>)> $! \)
-> \[i]('$i;:$;$#10;' ! \)
-> $(last..first:-1)
-> '$...;$#10;' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
5:Miller
4:Fletcher
3:Baker
2:Cooper
1:Smith
</pre>
===Re-using the solver we created for the Zebra puzzle===
<syntaxhighlight lang="tailspin">
// We add a zero to be able to express e.g. "not top floor"
def floors: [0..5 -> (floor:$)];
def names: [['Ground', 'Baker', 'Cooper', 'Fletcher', 'Miller', 'Smith']... -> (name:$)];
def dwellings: [$floors, $names] -> \(
def solver: $ -> EinsteinSolver;
{name: 'Ground', floor: 0} -> !solver::isFact
({name: 'Ground'} solver::nextTo&{byField: :(floor:), bMinusA: [1..4]} {name: 'Baker'}) -> !VOID
({name: 'Ground'} solver::nextTo&{byField: :(floor:), bMinusA: [2..5]} {name: 'Cooper'}) -> !VOID
({name: 'Ground'} solver::nextTo&{byField: :(floor:), bMinusA: [2..4]} {name: 'Fletcher'}) -> !VOID
({name: 'Cooper'} solver::nextTo&{byField: :(floor:), bMinusA: [1..4]} {name: 'Miller'}) -> !VOID
({name: 'Fletcher'} solver::nextTo&{byField: :(floor:), bMinusA: [-4..-2, 2..4]} {name: 'Smith'}) -> !VOID
({name: 'Fletcher'} solver::nextTo&{byField: :(floor:), bMinusA: [-4..-2, 2..4]} {name: 'Cooper'}) -> !VOID
[$solver::solutions&{required: 6} ... -> ($ notMatching {| {name: 'Ground'} |})]!
\);
$dwellings -> \[i]('Solution $i;:
$... -> '$;
';
'! \)... -> !OUT::write
'No more solutions
' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
Solution 1:
{floor=1, name=Smith}
{floor=5, name=Miller}
{floor=2, name=Cooper}
{floor=4, name=Fletcher}
{floor=3, name=Baker}
No more solutions
</pre>
Line 3,766 ⟶ 4,665:
that produce a value that is/can be interpreted as a boolean.
{{tcllib|struct::list}}
<
package require struct::list
Line 3,796 ⟶ 4,695:
}
return $result
}</
Solve the particular problem:
<
{$Baker != 5}
{$Cooper != 1}
Line 3,808 ⟶ 4,707:
}]
puts "Solution found:"
foreach {where who} $soln {puts " Floor ${where}: $who"}</
{{out}}
Line 3,818 ⟶ 4,717:
Floor 4: Fletcher
Floor 5: Miller
</pre>
Line 3,898 ⟶ 4,722:
{{works with|Bash}}
<
# NAMES is a list of names. It can be changed as needed. It can be more than five names, or less.
Line 3,970 ⟶ 4,794:
fi
done
done</
Sample output:
Line 3,977 ⟶ 4,801:
=={{header|UTFool}}==
<syntaxhighlight lang="utfool">
···
http://rosettacode.org/wiki/Dinesman's_multiple-dwelling_problem
Line 4,025 ⟶ 4,849:
people.insert i, person
house.setLength house.length° - 1
</syntaxhighlight>
'''Output''':
<pre>SCBFM</pre>
Line 4,032 ⟶ 4,856:
{{trans|Kotlin}}
{{libheader|Wren-seq}}
<
var permute // recursive
Line 4,039 ⟶ 4,863:
var perms = []
var toInsert = input[0]
for (perm in permute.call(input.skip(1).toList)) {
for (i in 0..perm.count) {
Line 4,080 ⟶ 4,903:
System.print()
}
}</
{{out}}
Line 4,095 ⟶ 4,918:
=={{header|XPL0}}==
{{incomplete|XPL0|Examples should state what changes to the problem text are allowed.}}
<
int B, C, F, M, S;
for B:= 1 to 4 do \Baker does not live on top (5th) floor
Line 4,111 ⟶ 4,934:
Text(0, "Miller "); IntOut(0, M); CrLf(0);
Text(0, "Smith "); IntOut(0, S); CrLf(0);
]</
Output:
Line 4,128 ⟶ 4,951:
This could be generalized even more by putting the variables and constraint functions in a class, then reflection could be used to automagically get the variables, variable names and constraint functions.
<
const bottom=1,top=5; // floors: 1..5
// All live on different floors, enforced by using permutations of floors
Line 4,147 ⟶ 4,970:
break;
}
}</
{{out}}
<pre>
L(L("Baker",3),L("Cooper",2),L("Fletcher",4),L("Miller",5),L("Smith",1))
</pre>
|