So I had the bright idea to do a screencast of me solving the problem and posting it on youtube... any feedback is welcome! And if it goes well, maybe I'll do more of them in the future :) We'll see! I haven't done youtube before, so this is my first video on there!
Hmm I should try that IRL, how much does a deck of cards Go for nowadays?
shuffle.go
packageshuffleimport("errors")// Faro interweaves two halves of a slice, leaving the first and last elements unchangedfuncFaro(deck[]string)([]string,error){size:=len(deck)ifsize%2!=0{returnnil,errors.New("deck must be of an even size")}// if the size is empty or just two, simply return the deckifsize<=2{returndeck,nil}left:=deck[:(size/2)]right:=deck[(size/2):]shuffled:=[]string{}fori:=rangeleft{shuffled=append(shuffled,left[i],right[i])}returnshuffled,nil}
shuffle_test.go
packageshuffleimport"testing"funcequal(result[]string,expected[]string)bool{iflen(result)!=len(expected){returnfalse}fori:=rangeresult{ifresult[i]!=expected[i]{returnfalse}}returntrue}funcTestFaro(t*testing.T){testCases:=[]struct{descriptionstringinput[]stringexpected[]stringexpectErrbool}{{"empty slice",[]string{},[]string{},false,},{"returns error on odd sized slice",[]string{"ace","one","two"},nil,true,},{"only two entries",[]string{"ace","king"},[]string{"ace","king"},false,},{"small deck",[]string{"ace","two","three","four"},[]string{"ace","three","two","four"},false,},{"post example",[]string{"ace","two","three","four","five","six"},[]string{"ace","four","two","five","three","six"},false,},}for_,test:=rangetestCases{result,err:=Faro(test.input)iferr==nil&&test.expectErr{t.Fatalf("FAIL: %s - Faro(%+v) - expected error to be thrown",test.description,test.input)}if!equal(result,test.expected){t.Fatalf("FAIL: %s - Faro(%+v): %+v, %+v - expected '%+v'",test.description,test.input,result,err,test.expected)}t.Logf("PASS: %s",test.description)}}
.map((_,i) : "i" will be the index of the current element, we don't need to work with the value here
We return a value located inside the input, at the following index:
If we are in an odd space, the targeted index will be i/2 + true * (a.length / 2 + 0.5). Thanks to coercion, "true" will be translated to 1, hence we will fetch the (a.length / 2 + 0.5)+i/2th index
Else if we are in an even space, the target will be i/2 + false * (a.length / 2 + 0.5), translated to i/2 + 0 * (a.length / 2 + 0.5) (hence, i/2)
Taking into account that the input is an array, you could save some bytes by replacing [...a] with just a (for golf purposes).
Apart from that, the solution seems really specific to the problem, and doesn't work for different arrays. For example:
f(['ace','two','three','four','five','six','seven','eight'])//["ace", "four", "two", "five", "three", "six", "four", "seven"]// there are 2 "four" and no "eight"
#!/usr/bin/perlusewarnings;usestrict;sub faro_shuffle{my($deck)=@_;die"Odd number of cards.\n"if@$deck%2;my$mid=@$deck/2;return[map@$deck[$_,$mid+$_],0..$mid-1]}useTest::Moretests=>5;useTest::Exception;is_deeplyfaro_shuffle([]),[],'empty';is_deeplyfaro_shuffle(['ace','two']),['ace','two'],'two cards';is_deeplyfaro_shuffle(['ace','two','three','four']),['ace','three','two','four'],'small deck';is_deeplyfaro_shuffle(['ace','two','three','four','five','six']),['ace','four','two','five','three','six'],'original example';throws_ok{faro_shuffle(['ace','two','three'])}qr/^Odd number of cards\.$/,"odd number exception";
19 yo student *and* a full-time developer.
Building with Rails currently, exploring new frontiers.
I enjoy functional programming, Linux, FOSS, refactoring and mentoring :)
I wanted to do it simple - Strings and flat_map()s, but here's a bit more involved solution, with generics, trait bounds, and an awesome case for the itertools crate :)
Programmer and mathematician. Problem solver. Lover of clean code, coffee, cycling, running and Italian food.
Kotlin, Java, Spock (Groovy), PHP, Angular, MariaDB, ...
Haskell:
i feel in my bones there's wholly point-free way to do it but can't quite get there right now
I managed to get it point free!
I remember looking for the
splitAtfunction when I was writing my first answer, not sure how I missed it in hoogle.Also, I've never seen
Control.Arrowbefore (I'm pretty new to Haskell). Seems useful.Bit of practice with
flatMap; I hadn't used it before - but I'm going to start now!EDIT:
So I had the bright idea to do a screencast of me solving the problem and posting it on youtube... any feedback is welcome! And if it goes well, maybe I'll do more of them in the future :) We'll see! I haven't done youtube before, so this is my first video on there!
youtu.be/srT3yqFsgCQ
Nicely done on the video! Very clear, and nicely put together. :-)
Thanks!
Hmm I should try that IRL, how much does a deck of cards Go for nowadays?
shuffle.go
shuffle_test.go
A bit of golf:
It works like this:
.map((_,i): "i" will be the index of the current element, we don't need to work with the value herei/2 + true * (a.length / 2 + 0.5). Thanks to coercion, "true" will be translated to1, hence we will fetch the(a.length / 2 + 0.5)+i/2th indexi/2 + false * (a.length / 2 + 0.5), translated toi/2 + 0 * (a.length / 2 + 0.5)(hence,i/2)The return will then be the following:
Taking into account that the input is an array, you could save some bytes by replacing
[...a]with justa(for golf purposes).Apart from that, the solution seems really specific to the problem, and doesn't work for different arrays. For example:
Thanks a lot for the input! The problem was in the
2.5usage, which had to be replaced witha.length/2-.5. I updated my answer!You can shorten the index computation to:
Python (golfing, and assuming we want to mutate the input list)
The idea is to use as index
We can however factor
//2so we getThen we can use right shift
>>to get rid of parenthesis to the finalA solution just returning the shuffled array instead could be:
Basically using a recusive function picking one element from each half everytime until both are empty.
Perl solution. Tests stolen from Donald Feury.
python
Oh, it's been a while since I've had bandwidth to participate. Today's was nice & relaxing, though. Just what I need before a flight.
Here's mine:
Full version w/ tests at gist.github.com/kerrishotts/bde389...
I wanted to do it simple -
Strings andflat_map()s, but here's a bit more involved solution, with generics, trait bounds, and an awesome case for the itertools crate :)My solution in JavaScript
If you like shuffling card decks in this way a lot, see projecteuler.net/problem=622 for an interesting puzzle!