Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
Given a string that contains only lowercase English letters, I am writing an Elixir function that finds the first non-repeating character in it and returns its index or else -1.
Examples:
s = "leetcode"
should return 0 because "l" is the first character that does not repeat and the zero-based index is 0
s = "loveleetcode"
should return 2 because v is the first character that does not repeat and the zero-based index is 2
The following is my solution so far, can you make it better or fix it?
defmodule Algos do
def first_unique_char_index(str) do
arr = String.split(str, "", trim: true)
indexes = Enum.with_index(arr)
first = Enum.frequencies(arr)
|> Map.to_list
|> Enum.sort(fn ({a,_b}, {c,_d}) ->
{_char1, i1} = Enum.find(indexes, (fn {x,_i} -> x == a end))
{_char2, i2} = Enum.find(indexes, (fn {y,_j} -> y == c end))
i1 <= i2
end)
|> Enum.find(fn {_char, num} -> num == 1 end)
case first do
{char, _num} ->
result = Enum.find(indexes, fn {x, _i} -> char == x end)
{_letter, index} = result
index
nil ->
-1
end
end
end
Algos.first_unique_char_index("aabcc") # returns 2
Algos.first_unique_char_index("picadillo") # returns 0
Algos.first_unique_char_index("dood") # returns -1
As a sindenote, the problem is from the "first unique character in a string" LeetCode puzzle.
The below is probably the most performant solution; I decided to put it here because it reveals several interesting tricks.
"leetcode"
|> to_charlist()
|> Enum.with_index() # we need index to compare by
|> Enum.reduce(%{}, fn {e, i}, acc ->
# trick for the future: `:many > idx` for any integer `idx` :)
Map.update(acc, e, {e, i}, &{elem(&1, 0), :many})
end)
|> Enum.sort_by(&elem(elem(&1, 1), 1)) # sort to get a head
|> case do
[{_, {_, :many}} | _] -> "All dups"
[{_, {result, index}} | _] -> {<<result>>, index}
_ -> "Empty input"
end
#⇒ {"l", 0}
This is a good little puzzle, and one that could be solved via a couple accumulators. Instead of splitting the string, you could work with the internal binary representation, or (in order to skip the extra complexity involved with encoding) you could convert the string to a character list and focus on the integer components.
Here's a possible solution (not thoroughly tested):
defmodule FirstUniq do
def char(string) do
[first_char | rest] = to_charlist(string)
eval_char(first_char, 0, rest, rest)
end
# Case where we hit the end of the string without a duplicate!
defp eval_char(_char, index, [], _), do: index
# Case where a character repeats... increment the index and eval next char
defp eval_char(char, index, [x | _], [next_char | rest]) when char == x do
eval_char(next_char, index + 1, rest, rest)
end
# Case where the character does not repeat: keep looking
defp eval_char(char, index, [x | rest], acc2) when char != x do
eval_char(char, index, rest, acc2)
end
end
# should be 0 (because "l" does not occur more than once)
IO.puts(FirstUniq.char("leetcode"))
# should be 2 (because "v" is the first char that does not repeat)
IO.puts(FirstUniq.char("loveleetcode"))
The hard work is done by the eval_char/4 function, whose multiple clauses act something like a case statement. The trick is we have to keep two accumulators, which is analogous to having a nested loop.
I would recommend Exercism's Elixir Track for presenting many of the common patterns that you'll encounter in the language.
Related
I'm trying to implement the "stock span problem" in Haskell. This is the solution I've come up with. Would like to see if there is any other idiomatic way to do this. this is O(n^2) algorithm (?) and using a stack, we can make it a O(n). Any pointers to the other higher order functions that can be used is appreciated.
import Data.List (inits)
type Quote = Int
type Quotes = [Quote]
type Span = [Int]
stockSpanQuad :: Quotes -> Span
stockSpanQuad [] = []
stockSpanQuad xs = map spanQ (map splitfunc (tail $ inits xs))
where
spanQ (qs, q) = 1 + (length $ takeWhile (\a -> a <= q) (reverse qs))
splitfunc xs = (init xs, last xs)
The link that you've provided contains a solution which uses stack data structure. The examples in every language mutate the stack, use the arrays with indexes and access the elements of the array by index. All these operations are not very common in Haskell.
Let's consider the following solution:
type Quote = Int
type Quotes = [Quote]
type Span = [Int]
stockSpanWithStack :: Quotes -> Span
stockSpanWithStack quotes = calculateSpan quotesWithIndexes []
where
quotesWithIndexes = zip quotes [0..]
calculateSpan [] _ = []
calculateSpan ((x, index):xs) stack =
let
newStack = dropWhile (\(y, _) -> y <= x) stack
stockValue [] = index + 1
stockValue ((_, x):_) = index - x
in
(stockValue newStack) : (calculateSpan xs ((x, index):newStack))
And let's compare it with the Python solution:
# Calculate span values for rest of the elements
for i in range(1, n):
# Pop elements from stack whlie stack is not
# empty and top of stack is smaller than price[i]
while( len(st) > 0 and price[st[0]] <= price[i]):
st.pop()
# If stack becomes empty, then price[i] is greater
# than all elements on left of it, i.e. price[0],
# price[1], ..price[i-1]. Else the price[i] is
# greater than elements after top of stack
S[i] = i+1 if len(st) <= 0 else (i - st[0])
# Push this element to stack
st.append(i)
For the stack solution, we need elements with indexes. It can be imitated like this:
quotesWithIndexes = zip quotes [0..]
The list of quotes is iterated recursively and instead of modifying a stack in every loop iteration, we can call the function with a modified value:
calculateSpan ((x, index):xs) stack =
The following line in Python (popping of elements of the stack, which are smaller than the current value):
while( len(st) > 0 and price[st[0]] <= price[i]):
st.pop()
Can be rewritten in Haskell as:
newStack = dropWhile (\(y, _) -> y <= x) stack
And calculation of a stock value:
S[i] = i+1 if len(st) <= 0 else (i - st[0])
Can be interpreted as:
stockValue [] = index + 1
stockValue ((_, x):_) = index - x
Below it was said, that it's not a common thing to modify the state of the variables, like S[i] = ... or st.append(i). But we can recursively call the function with new stack value and prepend the current result to it:
(stockValue newStack) : (calculateSpan xs ((x, index):newStack))
Technically, we push at the beginning of the list and drop the first elements of the list, because it's idiomatic and more performant way of working with lists in Haskell.
I've come up with the following, however I'm not sure if its "idiomatic". I think this is similar to #Igor's answer. Please comment.
{-# LANGUAGE BangPatterns #-}
stockSpanLinear :: Quotes -> Span
stockSpanLinear = reverse.snd.(foldl func ([],[]))
type Stack = [(Quote, Int)]
func :: (Stack, Span)-> Quote -> (Stack, Span)
func ([], []) q = ([(q, 1)], [1])
func p#((_, !i):pis, span) q = go p q (i+1)
where
go :: (Stack, Span) -> Quote -> Int -> (Stack, Span)
go (stack,span) q index = let ys = dropWhile (\(p, _) -> p <= q) stack
in case ys of
[] -> ((q, index):ys, index+1:span)
(_,i):_ -> ((q, index):ys, index-i:span)
From an unordered list of int, I want to have the smallest difference between two elements. I have a code that is working but way to slow. Can anyone sugest some change to improve the performance? Please explain why you did the change and what will be the performance gain.
let allInt = [ 5; 8; 9 ]
let sortedList = allInt |> List.sort;
let differenceList = [ for a in 0 .. N-2 do yield sortedList.Item a - sortedList.Item a + 1 ]
printfn "%i" (List.min differenceList) // print 1 (because 9-8 smallest difference)
I think I'm doing to much list creation or iteration but I don't know how to write it differently in F#...yet.
Edit: I'm testing this code on list with 100 000 items or more.
Edit 2: I believe that if I can calculte the difference and have the min in one go it should improve the perf a lot, but I don't know how to do that, anay idea?
Thanks in advance
The List.Item performs in O(n) time and is probably the main performance bottle neck in your code. The evaluation of differenceList iterates the elements of sortedList by index, which means the performance is around O((N-2)(2(N-2))), which simplifies to O(N^2), where N is the number of elements in sortedList. For long lists, this will eventually perform badly.
What I would do is to eliminate calls to Item and instead use the List.pairwise operation
let data =
[ let rnd = System.Random()
for i in 1..100000 do yield rnd.Next() ]
#time
let result =
data
|> List.sort
|> List.pairwise // convert list from [a;b;c;...] to [(a,b); (b,c); ...]
|> List.map (fun (a,b) -> a - b |> abs) // Calculates the absolute difference
|> List.min
#time
The #time directives lets me measure execution time in F# Interactive and the output I get when running this code is:
--> Timing now on
Real: 00:00:00.029, CPU: 00:00:00.031, GC gen0: 1, gen1: 1, gen2: 0
val result : int = 0
--> Timing now off
F#'s built-in list type is implemented as a linked list, which means accessing elements by index has to enumerate the list all the way to the index each time. In your case you have two index accesses repeated N-2 times, getting slower and slower with each iteration, as the index grows and each access needs to go through longer part of the list.
First way out of this would be using an array instead of a list, which is a trivial change, but grants you faster index access.
(*
[| and |] let you define an array literal,
alternatively use List.toArray allInt
*)
let allInt = [| 5; 8; 9 |]
let sortedArray = allInt |> Array.sort;
let differenceList = [ for a in 0 .. N-2 do yield sortedArray.[a] - sortedArray.[a + 1] ]
Another approach might be pairing up the neighbours in the list, subtracting them and then finding a min.
let differenceList =
sortedList
|> List.pairwise
|> List.map (fun (x,y) -> x - y)
List.pairwise takes a list of elements and returns a list of the neighbouring pairs. E.g. in your example List.pairwise [ 5; 8; 9 ] = [ (5, 8); (8, 9) ], so that you can easily work with the pairs in the next step, the subtraction mapping.
This way is better, but these functions from List module take a list as input and produce a new list as the output, having to pass through the list 3 times (1 for pairwise, 1 for map, 1 for min at the end). To solve this, you can use functions from the Seq module, which work with .NETs IEnumerable<'a> interface allowing lazy evaluation resulting usually in fewer passes.
Fortunately in this case Seq defines alternatives for all the functions we use here, so the next step is trivial:
let differenceSeq =
sortedList
|> Seq.pairwise
|> Seq.map (fun (x,y) -> x - y)
let minDiff = Seq.min differenceSeq
This should need only one enumeration of the list (excluding the sorting phase of course).
But I cannot guarantee you which approach will be fastest. My bet would be on simply using an array instead of the list, but to find out, you will have to try it out and measure for yourself, on your data and your hardware. BehchmarkDotNet library can help you with that.
The rest of your question is adequately covered by the other answers, so I won't duplicate them. But nobody has yet addressed the question you asked in your Edit 2. To answer that question, if you're doing a calculation and then want the minimum result of that calculation, you want List.minBy. One clue that you want List.minBy is when you find yourself doing a map followed by a min operation (as both the other answers are doing): that's a classic sign that you want minBy, which does that in one operation instead of two.
There's one gotcha to watch out for when using List.minBy: It returns the original value, not the result of the calculation. I.e., if you do ints |> List.pairwise |> List.minBy (fun (a,b) -> abs (a - b)), then what List.minBy is going to return is a pair of items, not the difference. It's written that way because if it gives you the original value but you really wanted the result, you can always recalculate the result; but if it gave you the result and you really wanted the original value, you might not be able to get it. (Was that difference of 1 the difference between 8 and 9, or between 4 and 5?)
So in your case, you could do:
let allInt = [5; 8; 9]
let minPair =
allInt
|> List.pairwise
|> List.minBy (fun (x,y) -> abs (x - y))
let a, b = minPair
let minDifference = abs (a - b)
printfn "The difference between %d and %d was %d" a b minDifference
The List.minBy operation also exists on sequences, so if your list is large enough that you want to avoid creating an intermediate list of pairs, then use Seq.pairwise and Seq.minBy instead:
let allInt = [5; 8; 9]
let minPair =
allInt
|> Seq.pairwise
|> Seq.minBy (fun (x,y) -> abs (x - y))
let a, b = minPair
let minDifference = abs (a - b)
printfn "The difference between %d and %d was %d" a b minDifference
EDIT: Yes, I see that you've got a list of 100,000 items. So you definitely want the Seq version of this. The F# seq type is just IEnumerable, so if you're used to C#, think of the Seq functions as LINQ expressions and you'll have the right idea.
P.S. One thing to note here: see how I'm doing let a, b = minPair? That's called destructuring assignment, and it's really useful. I could also have done this:
let a, b =
allInt
|> Seq.pairwise
|> Seq.minBy (fun (x,y) -> abs (x - y))
and it would have given me the same result. Seq.minBy returns a tuple of two integers, and the let a, b = (tuple of two integers) expression takes that tuple, matches it against the pattern a, b, and thus assigns a to have the value of that tuple's first item, and b to have the value of that tuple's second item. Notice how I used the phrase "matches it against the pattern": this is the exact same thing as when you use a match expression. Explaining match expressions would make this answer too long, so I'll just point you to an excellent reference on them if you haven't already read it:
https://fsharpforfunandprofit.com/posts/match-expression/
Here is my solution:
let minPair xs =
let foo (x, y) = abs (x - y)
xs
|> List.allPairs xs
|> List.filter (fun (x, y) -> x <> y)
|> List.minBy foo
|> foo
I'm writing a function called after which takes a list of integers and two integers as parameters. after list num1 num2 should return True if num1 occurs in the list and num2 occurs in list afternum1. (Not necessarily immediately after).
after::[Int]->Int->Int->Bool
after [] _ _=False
after [x:xs] b c
|x==b && c `elem` xs =True
|x/=b && b `elem` xs && b `elem` xs=True
This is what I have so far,my biggest problem is that I don't know how to force num2 to be after num1.
There's a few different ways to approach this one; while it's tempting to go straight for recursion on this, it's nice to
avoid using recursion explicitly if there's another option.
Here's a simple version using some list utilities. Note that it's a Haskell idiom that the object we're operating over is usually the last argument. In this case switching the arguments lets us write it as a pipeline with it's third argument (the list) passed implicitly:
after :: Int -> Int -> [Int] -> Bool
after a b = elem b . dropWhile (/= a)
Hopefully this is pretty easy to understand; we drop elements of the list until we hit an a, assuming we find one we check if there's a b in the remaining list. If there was no a, this list is [] and obviously there's no b there, so it returns False as expected.
You haven't specified what happens if 'a' and 'b' are equal, so I'll leave it up to you to adapt it for that case. HINT: add a tail somewhere ;)
Here are a couple of other approaches if you're interested:
This is pretty easily handled using a fold;
We have three states to model. Either we're looking for the first elem, or
we're looking for the second elem, or we've found them (in the right order).
data State =
FindA | FindB | Found
deriving Eq
Then we can 'fold' (aka reduce) the list down to the result of whether it matches or not.
after :: Int -> Int -> [Int] -> Bool
after a b xs = foldl go FindA xs == Found
where
go FindA x = if x == a then FindB else FindA
go FindB x = if x == b then Found else FindB
go Found _ = Found
You can also do it recursively if you like:
after :: Int -> Int -> [Int] -> Bool
after _ _ [] = False
after a b (x:xs)
| x == a = b `elem` xs
| otherwise = after a b xs
Cheers!
You can split it into two parts: the first one will find the first occurrence of num1. After that, you just need to drop all elements before it and just check that num2 is in the remaining part of the list.
There's a standard function elemIndex for the first part. The second one is just elem.
import Data.List (elemIndex)
after xs x y =
case x `elemIndex` xs of
Just i -> y `elem` (drop (i + 1) xs)
Nothing -> False
If you'd like to implement it without elem or elemIndex, you could include a subroutine. Something like:
after xs b c = go xs False
where go (x:xs) bFound
| x == b && not (null xs) = go xs True
| bFound && x == c = True
| null xs = False
| otherwise = go xs bFound
How should I go about removing a given element from a list? As an example, say I have list ['A'; 'B'; 'C'; 'D'; 'E'] and want to remove the element at index 2 to produce the list ['A'; 'B'; 'D'; 'E']? I've already written the following code which accomplishes the task, but it seems rather inefficient to traverse the start of the list when I already know the index.
let remove lst i =
let rec remove lst lst' =
match lst with
| [] -> lst'
| h::t -> if List.length lst = i then
lst' # t
else
remove t (lst' # [h])
remove lst []
let myList = ['A'; 'B'; 'C'; 'D'; 'E']
let newList = remove myList 2
Alternatively, how should I insert an element at a given position? My code is similar to the above approach and most likely inefficient as well.
let insert lst i x =
let rec insert lst lst' =
match lst with
| [] -> lst'
| h::t -> if List.length lst = i then
lst' # [x] # lst
else
insert t (lst' # [h])
insert lst []
let myList = ['A'; 'B'; 'D'; 'E']
let newList = insert myList 2 'C'
Removing element at the specified index isn't a typical operation in functional programming - that's why it seems difficult to find the right implementation of these operations. In functional programming, you'll usually process the list element-by-element using recursion, or implement the processing in terms of higher-level declarative operations. Perhaps if you could clarfiy what is your motivation, we can give a better answer.
Anyway, to implement the two operations you wanted, you can use existing higher-order functions (that traverse the entire list a few times, because there is really no good way of doing this without traversing the list):
let removeAt index input =
input
// Associate each element with a boolean flag specifying whether
// we want to keep the element in the resulting list
|> List.mapi (fun i el -> (i <> index, el))
// Remove elements for which the flag is 'false' and drop the flags
|> List.filter fst |> List.map snd
To insert element to the specified index, you could write:
let insertAt index newEl input =
// For each element, we generate a list of elements that should
// replace the original one - either singleton list or two elements
// for the specified index
input |> List.mapi (fun i el -> if i = index then [newEl; el] else [el])
|> List.concat
However, as noted earlier - unless you have a very good reasons for using these functions, you should probably consider describing your goals more broadly and use an alternative (more functional) solution.
Seems the most idiomatic (not tail recursive):
let rec insert v i l =
match i, l with
| 0, xs -> v::xs
| i, x::xs -> x::insert v (i - 1) xs
| i, [] -> failwith "index out of range"
let rec remove i l =
match i, l with
| 0, x::xs -> xs
| i, x::xs -> x::remove (i - 1) xs
| i, [] -> failwith "index out of range"
it seems rather inefficient to
traverse the start of the list when I
already know the index.
F# lists are singly-linked lists, so you don't have indexed access to them. But most of the time, you don't need it. The majority of indexed operations on arrays are iteration from front to end, which is exactly the most common operation on immutable lists. Its also pretty common to add items to the end of an array, which isn't really the most efficient operation on singly linked lists, but most of the time you can use the "cons and reverse" idiom or use an immutable queue to get the same result.
Arrays and ResizeArrays are really the best choice if you need indexed access, but they aren't immutable. A handful of immutable data structures like VLists allow you to create list-like data structures supporting O(1) cons and O(log n) indexed random access if you really need it.
If you need random access in a list, consider using System.Collections.Generic.List<T> or System.Collections.Generic.LinkedList<T> instead of a F# list.
I know this has been here for a while now, but just had to do something like this recently and I came up with this solution, maybe it isn't the most efficient, but it surely is the shortest idiomatic code I found for it
let removeAt index list =
list |> List.indexed |> List.filter (fun (i, _) -> i <> index) |> List.map snd
The List.Indexed returns a list of tuples which are the index in the list and the actual item in that position after that all it takes is to filter the one tuple matching the inputted index and get the actual item afterwards.
I hope this helps someone who's not extremely concerned with efficiency and wants brief code
The following includes a bit of error checking as well
let removeAt index = function
| xs when index >= 0 && index < List.length xs ->
xs
|> List.splitAt index
|> fun (x,y) -> y |> List.skip 1 |> List.append x
| ys -> ys
Lets go thru it and explain the code
// use the function syntax
let removeAt index = function
// then check if index is within the size of the list
| xs when index >= 0 && index < List.length xs ->
xs
// split the list before the given index
// splitAt : int -> 'T list -> ('T list * 'T list)
// this gives us a tuple of the the list with 2 sublists
|> List.splitAt index
// define a function which
// first drops the element on the snd tuple element
// then appends the remainder of that sublist to the fst tuple element
// and return all of it
|> fun (x,y) -> y |> List.skip 1 |> List.append x
//index out of range so return the original list
| ys -> ys
And if you don't like the idea of simply returning the original list on indexOutOfRange - wrap the return into something
let removeAt index = function
| xs when index >= 0 && index < List.length xs ->
xs
|> List.splitAt index
|> fun (x,y) -> y |> List.skip 1 |> List.append x
|> Some
| ys -> None
I think this should be quite faster than Juliet's or Tomas' proposal but most certainly Mauricio's comment is hitting it home. If one needs to remove or delete items other data structures seem a better fit.
Given a set of possible values and a number of "digits," I want to find every unique, unordered grouping of values. For example, say you have an alphabet of A, B, C. All the combinations of 3 digits would be:
AAA
AAB
ABB
BBB
BBC
BCC
CCC
CCA
CAA
ABC
The specific problem I'm trying to solve is a bit simpler. I'm doing a BlackJack game as an exercise in F# (I've posted about this before). The way I'm calculating hand values is with a list of lists of cards' possible values. All cards except the Ace have a single item in the list, but the Aces can be either 1 or 11. The implementation I came up with in that post generates a lot of redundancy. For example, 3 aces would create a list like [3; 13; 13; 13; 23; 23; 23; 33]. Right now I'm taking the final list and running it through Distinct(), but it feels like a bit of a hack.
Tying this all together, the Aces' potential values (1, 11) constitutes the alphabet, and the number of aces in the hand determines the number of digits. In this case, I would want the algorithm to come up with the following pattern:
1, 1
1, 11
11,11
Something tells me Dynamic Programming may come into play here, but my lack of appropriate terminology is leaving me a bit stuck. Any help would be appreciated.
Edit
For what it's worth, I'm aware that there are much simpler solutions to the specific problem, but being an exercise in functional programming, generality is one of my goals.
Hmm, in your case it is enough to (1) count the Aces (let the count be N) and then (2) generate the possible total value as list comprehension of
{ i * 11 + (N - i) * 1 } | 0 <= i <= N }
... however you'd express that in F#. No need to do actual permutations, combinatorics etc.
This problem is a good brain teaser. It should be code golf. :)
let rec permute list count =
seq {
match list with
| y::ys when count > 0 ->
for n in permute list (count - 1) do
yield Seq.map (fun li -> y::li) n
yield Seq.concat (permute ys count)
| y::ys -> yield Seq.singleton []
| [] -> ()
}
Ace Example
permute ["1";"11"] 2
|> Seq.concat
|> Seq.iter (printfn "%A")
["1"; "1"]
["1"; "11"]
["11"; "11"]
ABC Example
permute ["A";"B";"C"] 3
|> Seq.concat
|> Seq.iter (printfn "%A");;
["A"; "A"; "A"]
["A"; "A"; "B"]
["A"; "A"; "C"]
["A"; "B"; "B"]
["A"; "B"; "C"]
["A"; "C"; "C"]
["B"; "B"; "B"]
["B"; "B"; "C"]
["B"; "C"; "C"]
["C"; "C"; "C"]
y::li is where all the concating work happens. You could replace it with y + li if all you wanted was strings. You also have to yield Seq.singleton an "" insted of []
Performance Update:
This problem memoizes nicely and gives much better performance memoized for none trivial cases.
let memoize2 f =
let cache = Dictionary<_,_>()
fun x y ->
let ok, res = cache.TryGetValue((x, y))
if ok then
res
else
let res = f x y
cache.[(x, y)] <- res
res
// permute ["A";"B";"C"] 400 |> Seq.concat |> Seq.length |> printf "%A"
// Real: 00:00:07.740, CPU: 00:00:08.234, GC gen0: 118, gen1: 114, gen2: 4
let rec permute =
memoize2(fun list count ->
seq {
match list with
| y::ys when count > 0 ->
for n in permute list (count - 1) do
yield Seq.map (fun li -> y::li) n |> Seq.cache
yield Seq.concat (permute ys count)
| y::ys -> yield Seq.singleton []
| [] -> ()
} |> Seq.cache)
I also memoized kvb solution and it performs 15% faster than mine.
// permute ["A";"B";"C"] 400 |> Seq.length |> printf "%A"
// Real: 00:00:06.587, CPU: 00:00:07.046, GC gen0: 87, gen1: 83, gen2: 4
let rec permute =
memoize2 (fun list n ->
match n with
| 0 -> Seq.singleton []
| n ->
seq {
match list with
| x::xs ->
yield! permute list (n-1) |> Seq.map (fun l -> x::l)
yield! permute xs n
| [] -> ()
} |> Seq.cache)
Here's a semi-faithful translation of Thomas Pornin's answer to F#. Note that I don't expect this to be particularly more performant than the naive approach using distinct, but it's definitely neater:
let rec splits l = function
| [] -> Seq.empty
| x::xs -> seq {
yield [],x,xs
for l,y,ys in splits xs do
yield x::l,y,ys
}
let rec combs s = function
| 0 -> Seq.singleton []
| n -> seq {
for _,x,rest in splits s do
for l in combs (x::rest) (n-1) do
yield x::l
}
Or, a variation on gradbot's solution instead:
let rec permute list = function
| 0 -> Seq.singleton []
| n -> seq {
match list with
| x::xs ->
yield! permute list (n-1) |> Seq.map (fun l -> x::l)
yield! permute xs n
| [] -> ()
}
You can do it recursively. I am writing this in Java; my F# is not good enough:
static void genCombInternal(int num, int[] base,
int min, int max, Collection<int[]> dst)
{
if (num == 0) {
dst.add(base);
return;
}
for (int i = min; i <= max; i ++) {
int[] nb = new int[base.length + 1];
System.arraycopy(base, 0, nb, 0, base.length);
nb[base.length] = i;
genCombInternal(num - 1, nb, i, max, dst);
}
}
static Collection<int[]> genComb(int num, int min, int max)
{
Collection<int[]> d = new ArrayList<int[]>();
genCombInternal(num, new int[0], min, max, d);
return d;
}
This code is completely untested. If it works, then calling genComb(num, min, max) should generate all your "combinations" of num integers in the range min to max (inclusive), such that no two returned combinations are equal save for ordering.
This is very close to the code which generates "true" combinations. The trick is in the allowed integers at each step: if you change i into i+1 in the recursive call, then you should get the mathematical combinations.
Given your "alphabet" of {1,11}, then you basically want to generate all "words" of length n, where n is the number of aces, such that all of the 1's (0 or more) are to the left and all of the 11's are to the right. The ordering does not matter, this is just a simple approach to iterate through the combinations that you care about.
In Python:
n = 3 # number of aces
hands = []
for i in range(0,n+1):
hands.append([1] * (n-i) + [11] * i)
Or even simpler in Python:
hands = [[1]*(n-i) + [11]*i for i in range(0,n+1)]
To get the total score per hand:
scores = [sum(hand) for hand in hands]
A note on Python syntax in case you are unfamiliar, brackets [] denote a list and [1]*x means create a new list that is the concatenation of x copies of [1]; that is,
[1] * x == [1,1,1]
if x = 3