September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -1,7 +1,7 @@
{{omit from|GUISS}}
;Task
Solve Dinesman's multiple dwelling [http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3.2 problem] but in a way that most naturally follows the problem statement given below.
Solve [https://web.archive.org/web/20170325033240/http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-28.html#%_sec_4.3.2 Dinesman's multiple dwelling problem] but in a way that most naturally follows the problem statement given below.
Solutions are allowed (but not required) to parse and interpret the problem text, but should remain flexible and should state what changes to the problem text are allowed. Flexibility and ease of expression are valued.

View file

@ -0,0 +1,18 @@
module Enumerable(T)
def index!(element)
index(element).not_nil!
end
end
residents = [:Baker, :Cooper, :Fletcher, :Miller, :Smith]
predicates = [
->(p : Array(Symbol)){ :Baker != p.last },
->(p : Array(Symbol)){ :Cooper != p.first },
->(p : Array(Symbol)){ :Fletcher != p.first && :Fletcher != p.last },
->(p : Array(Symbol)){ p.index!(:Miller) > p.index!(:Cooper) },
->(p : Array(Symbol)){ (p.index!(:Smith) - p.index!(:Fletcher)).abs != 1 },
->(p : Array(Symbol)){ (p.index!(:Cooper) - p.index!(:Fletcher)).abs != 1}
]
puts residents.permutations.find { |p| predicates.all? &.call p }

View file

@ -1,6 +1,18 @@
import Data.List (permutations)
print [ ("Baker lives on " ++ show b
, "Cooper lives on " ++ show c
, "Fletcher lives on " ++ show f
, "Miller lives on " ++ show m
, "Smith lives on " ++ show s) | [b,c,f,m,s] <- permutations [1..5], b/=5,c/=1,f/=1,f/=5,m>c,abs(s-f)>1,abs(c-f)>1]
main :: IO ()
main =
print
[ ( "Baker lives on " ++ show b
, "Cooper lives on " ++ show c
, "Fletcher lives on " ++ show f
, "Miller lives on " ++ show m
, "Smith lives on " ++ show s)
| [b, c, f, m, s] <- permutations [1 .. 5]
, b /= 5
, c /= 1
, f /= 1
, f /= 5
, m > c
, abs (s - f) > 1
, abs (c - f) > 1 ]

View file

@ -0,0 +1,101 @@
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

View file

@ -15,4 +15,4 @@ predicates = [
for sol in permutations(Names.seq):
if all(p(sol) for p in predicates):
print " ".join(Names.strings[s] for s in sol)
print(" ".join(x for x, y in sorted(zip(Names.strings, sol), key=lambda x: x[1])))

View file

@ -0,0 +1,22 @@
'''Dinesman's multiple-dwelling problem'''
from itertools import permutations
print([
(
'Baker on ' + str(b),
'Cooper on ' + str(c),
'Fletcher on ' + str(f),
'Miller on ' + str(m),
'Smith on ' + str(s)
) for [b, c, f, m, s] in permutations(range(1, 6))
if all([
5 != b,
1 != c,
1 != f,
5 != f,
c < m,
1 < abs(s - f),
1 < abs(c - f)
])
])

View file

@ -0,0 +1,61 @@
'''Dinesman's multiple-dwelling problem'''
from itertools import chain, permutations
# main :: IO ()
def main():
'''Solution or null result.'''
print(report(
concatMap(dinesman)(
permutations(range(1, 6))
)
))
# dinesman :: (Int, Int, Int, Int, Int) -> [(Int, Int, Int, Int, Int)]
def dinesman(bcfms):
'''A list containing the given permutation of five
integers if it matches all the dinesman conditions,
or an empty list if it does not.
'''
[b, c, f, m, s] = bcfms
return [bcfms] if all([
5 != b,
1 != c,
1 != f,
5 != f,
c < m,
1 < abs(s - f),
1 < abs(c - f)
]) else []
# report :: [(Int, Int, Int, Int, Int)] -> String
def report(xs):
'''A message summarizing the first (if any) solution found.
'''
return ', '.join(list(map(
lambda k, n: k + ' in ' + str(n),
['Baker', 'Cooper', 'Fletcher', 'Miller', 'Smith'],
xs[0]
))) + '.' if xs else 'No solution found.'
# GENERAL -------------------------------------------------
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
'''A concatenated list over which a function has been mapped.
The list monad can be derived by using a function f which
wraps its output in a list,
(using an empty list to represent computational failure).
'''
return lambda xs: list(
chain.from_iterable(map(f, xs))
)
# MAIN ---
if __name__ == '__main__':
main()