Dating agency
- Scenario
A sailor signs up to a dating agency hoping to find a suitable mate.
The dating agency has 10 ladies on its books who may be suitable and uses the algorithm "all the nice girls love a sailor" to decide which ones to put forward for the sailor's consideration.
The sailor uses a different algorithm ("lady is lovable") to decide which ladies to actually date.
- Task
Model this scenario in your language.
Give the sailor and ladies some names.
Use some arbitrary method based on the ladies' names to determine whether they're nice and/or lovable. For preference, choose a method where the outcomes are (more or less) equally likely.
Hence, determine which ladies the dating agency should suggest and which of these the sailor should offer to date.
- Note
This task is intended as a bit of fun as well as a simple exercise in object modelling so hopefully it won't offend anyone!
Factor
<lang factor>USING: formatting io kernel math math.primes math.vectors prettyprint qw sequences sets ;
CONSTANT: ladies qw{
Abigail Emily Haley Leah Maru Penny Caroline Jodi Marnie Robin
}
CONSTANT: sailor "Willy"
- prime-root? ( n -- ? ) 1 - 9 mod 1 + prime? ; ! is the digital root prime?
- nice? ( lady sailor -- ? ) [ hashcode ] bi@ + prime-root? ; ! a lady is nice if the sum of the hashcode of her name and the sailor's name has a prime digit root
- lovable? ( lady sailor -- ? ) vdot prime-root? ; ! a lady is lovable if the dot product of her name and the sailor's name has a prime digital root
- nice ( -- seq ) ladies [ sailor nice? ] filter ;
- lovable ( -- seq ) ladies [ sailor lovable? ] filter ;
- compatible ( -- seq ) nice lovable intersect ;
- ladies. ( seq -- ) ", " join print ;
"lady nice? lovable?" print "------------------------------" print ladies [
dup sailor [ nice? ] [ lovable? ] bi-curry bi [ "yes" "no" ? ] bi@ "%-10s %-10s %-10s\n" printf
] each nl
"Based on this analysis:" print nl "The dating agency should suggest the following dates:" print nice ladies. nl sailor "And %s should offer to date these ones:\n" printf lovable ladies. nl sailor "But just between us, only the following ladies are compatible with %s:\n" printf compatible ladies.</lang>
- Output:
lady nice? lovable? ------------------------------ Abigail no yes Emily no no Haley no no Leah no no Maru yes no Penny yes no Caroline no yes Jodi no yes Marnie yes no Robin yes yes Based on this analysis: The dating agency should suggest the following dates: Maru, Penny, Marnie, Robin And Willy should offer to date these ones: Abigail, Caroline, Jodi, Robin But just between us, only the following ladies are compatible with Willy: Robin
Phix
Nowt fancy here, but at least I made some notes as I was translating things:
Fields are private by default and need to be made explicitly public, whereas methods
are the other way round and need to be made explicitly private when that is wanted.
Phix classes don't really play nice with functions like apply and filter, hence the need
for several little shims (new_lady/lady_names/sailor_love). There is no equivalent to the
implicit "toString", and no plans for one, though you could easily write an explicit one.
The "Lady lady = ladies[i]; lady.name" programming style is generally preferred: trying to
use say "ladies[i].name" simply will not work, instead "class x = ladies[i]; x.name" is
the correct way to write generic class code in Phix, should you genuinely need that.
No attempt has even been started on transpilation of class based code to JavaScript.
Booleans in Phix are just integers, and need to be printed with %t rather than %s.
Of course all this is open source, yada-yada-ya.
without javascript_semantics include structs.e function digital_root(integer n) assert(n>=0) while n>9 do integer tot = 0 while n>0 do tot += remainder(n,10) n = floor(n/10) end while n = tot end while return n end function class Lady public string name function lovable() return odd(sum(name)) end function function love(class s) if get_struct_name(s)!="Sailor" then return null end if // indeterminate return digital_root(sum(name)) > 4 end function end class function new_lady(string name) return new(Lady,{name}) end function function lady_names(sequence ladies) sequence res = repeat(0,length(ladies)) for i=1 to length(res) do Lady lady = ladies[i] res[i] = lady.name end for return join(res,", ") end function class Sailor public string name function love(Lady l) if get_struct_name(l)!="Lady" then return null end if // indeterminate return l.lovable() end function end class constant names = {"Ada", "Crystal", "Elena", "Euphoria", "Janet", "Julia", "Lily", "Miranda", "Perl", "Ruby"}, ladies = apply(names,new_lady) Sailor sailor = new({"Pascal"}) sequence eligibles = {} function sailor_love(Lady lady) return sailor.love(lady) end function printf(1,"%-10s %-12s %s\n", {"lady", "loves sailor", "lovable"}) printf(1,"%-10s %-12s %s\n", {"----", "------------", "-------"}) for i=1 to length(ladies) do Lady lady = ladies[i] bool lovesSailor = lady.love(sailor) if lovesSailor then eligibles = append(eligibles,lady) end if printf(1,"%-10s %-12t %t\n", {lady.name, lovesSailor, lady.lovable()}) end for printf(1,"\nBased on this analysis:") printf(1,"\nThe dating agency should suggest the following ladies:\n") printf(1,"%s\n",lady_names(eligibles)) printf(1,"\nand %s should offer to date these ones:\n",{sailor.name}) printf(1,"%s\n",lady_names(filter(eligibles,sailor_love)))
- Output:
lady loves sailor lovable ---- ------------ ------- Ada false false Crystal true false Elena true true Euphoria false true Janet false false Julia true true Lily true false Miranda true false Perl true true Ruby false false Based on this analysis: The dating agency should suggest the following ladies: Crystal, Elena, Julia, Lily, Miranda, Perl and Pascal should offer to date these ones: Elena, Julia, Perl
Python
<lang python>""" Jokes about courtesans aside, the selection process is by the letters of the names. If the integer corresponding to the ASCII character of the first letter of the name is even, the woman is considered nice. If the integers of the last letter of the lady's name and the sailor's name are both odd or both even, the sailor should consider the lady as lovable. """
sailors = ['Adrian', 'Caspian', 'Dune', 'Finn', 'Fisher', 'Heron', 'Kai',
'Ray', 'Sailor', 'Tao']
ladies = ['Ariel', 'Bertha', 'Blue', 'Cali', 'Catalina', 'Gale', 'Hannah',
'Isla', 'Marina', 'Shelly']
def isnicegirl(s):
return ord(s[0]) % 2 == 0
def islovable(slady, ssailor):
return ord(slady[-1]) % 2 == ord(ssailor[-1]) % 2
for lady in ladies:
if isnicegirl(lady): print("Dating service should offer a date with", lady) for sailor in sailors: if islovable(lady, sailor): print(" Sailor", sailor, "should take an offer to date her.") else: print("Dating service should NOT offer a date with", lady)
</lang>
- Output:
Dating service should NOT offer a date with Ariel Dating service should offer a date with Bertha Sailor Dune should take an offer to date her. Sailor Kai should take an offer to date her. Sailor Ray should take an offer to date her. Sailor Tao should take an offer to date her. Dating service should offer a date with Blue Sailor Dune should take an offer to date her. Sailor Kai should take an offer to date her. Sailor Ray should take an offer to date her. Sailor Tao should take an offer to date her. Dating service should NOT offer a date with Cali Dating service should NOT offer a date with Catalina Dating service should NOT offer a date with Gale Dating service should offer a date with Hannah Sailor Adrian should take an offer to date her. Sailor Caspian should take an offer to date her. Sailor Finn should take an offer to date her. Sailor Fisher should take an offer to date her. Sailor Heron should take an offer to date her. Sailor Sailor should take an offer to date her. Dating service should NOT offer a date with Isla Dating service should NOT offer a date with Marina Dating service should NOT offer a date with Shelly
Raku
Welcome to the Arbitrary and Capricious Dating Agency, (We don't use zodiacs, but we're just as arbitrary!)
<lang perl6>use Digest::SHA1::Native;
my %ladies = < Alice Beth Cecilia Donna Eunice Fran Genevieve Holly Irene Josephine Kathlene Loralie Margaret
Nancy Odelle Pamela Quinci Rhonda Stephanie Theresa Ursula Victoria Wren Yasmine Zoey >.map: -> $name { $name => { loves => :16(sha1-hex($name).substr(0,4)), lovable => :16(sha1-hex($name).substr(*-4)) }
}
my %sailors = < Ahab Brutus Popeye >.map: -> $name {
$name => { loves => :16(sha1-hex($name).substr(0,4)), lovable => :16(sha1-hex($name).substr(*-4)) }
}
for %sailors.sort( *.key ) -> $sailor {
printf "%6s will like: ", $sailor.key; say join ', ', my @likes = %ladies.sort( { abs $sailor.value.<loves> - .value.<loves> } ).head(10)».key; print ' Is liked by: '; say join ', ', my @liked = %ladies.sort( { abs $sailor.value.<lovable> - .value.<lovable> } ).head(10)».key; my %matches; for @liked.reverse Z, (1..10) { %matches{.[0]} += .[1] }; for @likes.reverse Z, (1..10) { %matches{.[0]} += .[1] }; say 'Best match: ' ~ %matches.max( *.value ).key; say ;
}</lang>
Ahab will like: Eunice, Ursula, Irene, Holly, Fran, Genevieve, Zoey, Donna, Cecilia, Alice Is liked by: Nancy, Theresa, Victoria, Genevieve, Alice, Rhonda, Kathlene, Odelle, Eunice, Pamela Best match: Genevieve Brutus will like: Beth, Nancy, Quinci, Odelle, Josephine, Kathlene, Theresa, Rhonda, Wren, Margaret Is liked by: Yasmine, Margaret, Loralie, Holly, Wren, Fran, Quinci, Eunice, Alice, Victoria Best match: Quinci Popeye will like: Loralie, Theresa, Stephanie, Yasmine, Alice, Cecilia, Donna, Zoey, Nancy, Genevieve Is liked by: Loralie, Margaret, Holly, Wren, Yasmine, Fran, Quinci, Eunice, Alice, Victoria Best match: Loralie
Wren
<lang ecmascript>import "./math" for Int, Nums import "./fmt" for Fmt
class Lady {
construct new(name) { _name = name }
name { _name }
// Sum the ASCII values of the characters in the ladies' names and find the digital root. // If it's more than 4, they're 'nice'. nice { var sum = Nums.sum(_name.bytes) return Int.digitalRoot(sum)[0] > 4 }
// Sum the ASCII values of the characters in the ladies' names. // If it's odd, they're 'lovable'. lovable { var sum = Nums.sum(_name.bytes) return sum % 2 == 1 }
love(s) { if (!(s is Sailor)) return null // indeterminate return nice }
toString { _name }
}
class Sailor {
construct new(name) { _name = name }
name { _name }
love(l) { if (!(l is Lady)) return null // indeterminate return l.lovable }
toString { _name }
}
var names = ["Ada", "Crystal", "Elena", "Euphoria", "Janet", "Julia", "Lily", "Miranda", "Perl", "Ruby"] var ladies = names.map { |n| Lady.new(n) }.toList var sailor = Sailor.new("Pascal") var eligibles = [] var format = "$-10s $-12s $s" Fmt.print(format, "lady", "loves sailor", "lovable") Fmt.print(format, "----", "------------", "-------") for (lady in ladies) {
var lovesSailor = lady.love(sailor) if (lovesSailor) eligibles.add(lady) Fmt.print(format, lady, lovesSailor, lady.lovable)
} System.print("\nBased on this analysis:") System.print("\nThe dating agency should suggest the following ladies:") System.print(eligibles) System.print("\nand %(sailor) should offer to date these ones:") System.print(eligibles.where { |e| sailor.love(e) }.toList)</lang>
- Output:
lady loves sailor lovable ---- ------------ ------- Ada false false Crystal true false Elena true true Euphoria false true Janet false false Julia true true Lily true false Miranda true false Perl true true Ruby false false Based on this analysis: The dating agency should suggest the following ladies: [Crystal, Elena, Julia, Lily, Miranda, Perl] and Pascal should offer to date these ones: [Elena, Julia, Perl]