Skip to content

Instantly share code, notes, and snippets.

@shadeglare
Last active December 24, 2015 05:49
Show Gist options
  • Save shadeglare/6753371 to your computer and use it in GitHub Desktop.
Save shadeglare/6753371 to your computer and use it in GitHub Desktop.
F sharp passenger tattoo assignment concept
open System
type PassengerType =
| Adult
| Children
| Infant
type Passenger = {
FirstName: String;
LastName: String;
Type: PassengerType;
}
let passengers = [
{ FirstName = "first1"; LastName = "last1"; Type = Adult };
{ FirstName = "first2"; LastName = "last2"; Type = Infant };
{ FirstName = "first3"; LastName = "last3"; Type = Adult };
{ FirstName = "first4"; LastName = "last4"; Type = Children };
{ FirstName = "first5"; LastName = "last5"; Type = Children };
{ FirstName = "first6"; LastName = "last6"; Type = Infant };
{ FirstName = "first7"; LastName = "last7"; Type = Adult };
]
let adults, children, infants =
let FilterPassenger passengerType =
List.filter (fun p -> p.Type = passengerType) passengers
FilterPassenger Adult, FilterPassenger Children, FilterPassenger Infant
let pairs, freeAdults =
let rec Pairwise pairs frees = function
| adult::adults, infant::infants ->
let pair = adult, infant
Pairwise (pair::pairs) frees (adults, infants)
| adults, _ -> pairs, frees @ adults
Pairwise [][] (adults, infants)
let childWithTattoo, freeAdultsWithTattoo, pairsWithTattoo =
let offsetRef = ref 1
let TattooWithGap gap =
let currentOffset = !offsetRef
List.mapi (fun i v ->
incr offsetRef
currentOffset + i * gap, v)
TattooWithGap 1 children, TattooWithGap 1 freeAdults, TattooWithGap 2 pairs
for tatoo, child in childWithTattoo do
printfn "%i %s" tatoo child.FirstName
printfn ""
for tatoo, adult in freeAdultsWithTattoo do
printfn "%i %s" tatoo adult.FirstName
printfn ""
for tatoo, (adult, infant) in pairsWithTattoo do
printfn "%i %s %s" tatoo adult.FirstName infant.FirstName
@s-kaspar
Copy link

more idiomatic version

type PaxType = 
   | Adult 
   | Children 
   | Infant

type Pax = 
   { FirstName : string
     LastName  : string
     Type      : PaxType }

let paxes = 
   [{ FirstName = "first1"; LastName = "last1"; Type = Adult }
    { FirstName = "first2"; LastName = "last2"; Type = Infant }
    { FirstName = "first3"; LastName = "last3"; Type = Adult }
    { FirstName = "first4"; LastName = "last4"; Type = Children }
    { FirstName = "first5"; LastName = "last5"; Type = Children }
    { FirstName = "first6"; LastName = "last6"; Type = Infant }
    { FirstName = "first7"; LastName = "last7"; Type = Adult }]

let adults, children, infants = 
   let filter ty =  List.filter (fun p -> p.Type = ty) paxes
   filter Adult, filter Children, filter Infant

let PairwiseAdultsWithInfants adults infants =
   let rec loop (pairs, frees) = function
      | [], _ -> pairs, frees
      | adult::rest, [] ->  loop (pairs, adult::frees) (rest, [])
      | adult::adtrest, inf::infrest -> loop ((adult, inf)::pairs, frees) (adtrest, infrest)
   loop ([],[]) (adults, infants)

let pairs, freeAdults = PairwiseAdultsWithInfants adults infants

let mapiWithOffset size offset = List.mapi (fun i v -> i * size + offset, v)

let tattooOffset = 1

let childWithTattoo = mapiWithOffset 1 tattooOffset children

let freeAdultsWithTattoo = mapiWithOffset 1 (tattooOffset + children.Length) freeAdults

let pairsWithTattoo = mapiWithOffset 2 (tattooOffset + children.Length + freeAdults.Length) pairs


for tatoo, child in childWithTattoo do 
   printfn "%i %s" tatoo child.FirstName
printfn ""

for tatoo, adult in freeAdultsWithTattoo do 
   printfn "%i %s" tatoo adult.FirstName
printfn ""

for tatoo, (adult, infant) in pairsWithTattoo do 
   printfn "%i %s %s" tatoo adult.FirstName infant.FirstName 

@s-kaspar
Copy link

finally, simplify

let pairs, freeAdults = 
   let rec pairwise pairs frees = function
      | adult::adults, infant::infants -> 
         let pair = adult, infant
         pairwise (pair::pairs) frees (adults, infants)
      | adults, _ -> pairs, frees @ adults
   pairwise [] [] (adults, infants)

@s-kaspar
Copy link

without noise

let children, (pairs, freeAdults) = 
   let rec pairwise pairs frees = function
      | adult::adults, infant::infants -> 
         let pairs = (adult, infant)::pairs
         pairwise pairs frees (adults, infants)
      | adults, _ -> pairs, frees @ adults

   let filter ty =  List.filter (fun p -> p.Type = ty) paxes
   filter Children, pairwise [] [] (filter Adult, filter Children)


let childWithTattoo, freeAdultsWithTattoo, pairsWithTattoo =
   let offset = ref 0
   let tatooise gap = 
      List.mapi (fun i v -> 
         incr offset
         i * gap + !offset, v)
   tatooise 1 children, tatooise 1 freeAdults, tatooise 2  pairs

@shadeglare
Copy link
Author

Fixed according to the best practice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment