This might be a Windows-centric problem. In any event, I decided to play around with Von-Neumann ordinals in SML. This is an encoding of the natural numbers in which each number is represented by a pure set -- a set whose elements are themselves sets.
I wrote the following code:
datatype set = EMPTY | SET of set list;
fun succ EMPTY = SET [EMPTY]
| succ (SET sets) = SET (sets # [SET sets]);
fun ordinal 0 = EMPTY
| ordinal n = succ (ordinal (n-1));
fun pprint S e =
let
fun f EMPTY = e
| f (SET sets) = "{" ^ (String.concatWith "," (map f sets)) ^ "}"
in
f S
end;
fun display n e = print ( "\n" ^ (pprint (ordinal n) e ) ^ "\n\n");
The display function takes a natural number and a string representation of the empty set. For example:
- display 3 "O";
{O,{O},{O,{O}}}
val it = () : unit
(which meshes with the Wikipedia entry on Von Neumann Ordinals). As a flourish I wanted to use an "O" with a stroke through it, so I did the following:
- display 3 "\195\152";
{Ø,{Ø},{Ø,{Ø}}}
}}
val it = () : unit
(You need to run chcp 65001 at the Window's command prompt before starting SML to get this to work).
There is a phantom line break in the middle of the string as well as an extra "}". I have no idea why. I've tried with other values of n and sometimes get phantom boxes in the middle of the line and always an extra "}". I've tried various work-arounds (short of ditching Windows for Linux) with no success.
Does anyone know a reliable way to print the empty set using a stroke through an "O" in SML?
Related
I am trying to write a function that returns true or false if a given string has exactly 6 consecutive characters with the same value. If the string has more or less than 6, it will return false:
I am not allowed to use lists, sets or import any packages. I am only restricted to while loops, for loops, and utilizing basic mathematical operations
Two example runs are shown below:
Enter a string: 367777776
True
Enter a string: 3677777777776
False
Note that although I entered numbers, it is actually a string within the function argument for example: consecutive('3777776')
I tried to convert the string into an ASCII table and then try and filter out the numbers there. However, I
def consecutive(x):
storage= ' '
acc=0
count=0
for s in x:
storage+= str(ord(s)) + ' '
acc+=ord(s)
if acc == acc:
count+=1
for s in x-1:
return count
My intention is to compare the previous character's ASCII code to the current character's ASCII code in the string. If the ASCII doesnt match, I will add an accumulator for it. The accumulator will list the number of duplicates. From there, I will implement an if-else statement to see if it is greater or less than 6 However, I have a hard time translating my thoughts into python code.
Can anyone assist me?
That's a pretty good start!
A few comments:
Variables storage and acc play the same role, and are a little more complicated than they have to be. All you want to know when you arrive at character s is whether or not s is identical to the previous character. So, you only need to store the previously seen character.
Condition acc == acc is always going to be True. I think you meant acc == s?
When you encounter an identical character, you correctly increase the count with count += 1. However, when we change characters, you should reset the count.
With these comments in mind, I fixed your code, then blanked out a few parts for you to fill. I've also renamed storage and acc to previous_char which I think is more explicit.
def has_6_consecutive(x):
previous_char = None
count = 0
for s in x:
if s == previous_char:
???
elif count == 6:
???
else:
???
previous_char = ???
???
You could use recursion. Loop over all the characters and for each one check to see of the next 6 are identical. If so, return true. If you get to the end of the array (or even within 6 characters of the end), return false.
For more info on recursion, check this out: https://www.programiz.com/python-programming/recursion
would something like this be allowed?
def consecF(n):
consec = 1
prev = n[0]
for i in n:
if i==prev:
consec+=1
else:
consec=1
if consec == 6:
return True
prev = i
return False
n = "12111123333221"
print(consecF(n))
You can try a two pointer approach, where the left pointer is fixed at the first instance of some digit and the right one is shifted as long as the digit is seen.
def consecutive(x):
left = 0
while left != len(x):
right = left
while right < len(x) and x[right] == x[left]:
right += 1
length = (right - 1) - left + 1 # from left to right - 1 inclusive, x[left] repeated
if length == 6: # found desired length
return True
left = right
return False # no segment found
tests = [
'3677777777776',
'367777776'
]
for test in tests:
print(f"{test}: {consecutive(test)}")
Output
3677777777776: False
367777776: True
You should store the current sequence of repeated chars.
def consecutive(x):
sequencechar = ' '
repetitions = 0
for ch in x:
if ch != sequencechar:
if repetitions == 6:
break
sequencechar = ch
repetitions = 1
else:
repetitions += 1
return repetitions == 6
If I could, I would not have given the entire solution, but this still is a simple problem. However one has to take care of some points.
As you see the current sequence is stored, and when the sequence is ended and a new starts, on having found a correct sequence it breaks out of the for loop.
Also after the for loop ends normally, the last sequence is checked (which was not done in the loop).
I wrote a PEG parser generator just for fun (I will publish it on NPM some time), and thought it would be easy to add a randomised phrase generator on top of it. The idea is to automatically get correct phrases, given a grammar. So I set the following rules to generate strings from each type of parsers :
Sequence p1 p2 ... pn : Generate a phrase for each subparser and return the concatenation.
Alternative p1 | p2 | ... | pn : Randomly pick a subparser and generate a phrase with it.
Repetition p{n, m} : Pick a number x in [n, m] (or [n, n+2] is m === Infinity) and return a concatenation of x generated phrases from p.
Terminal : Just return the terminal literal.
When I take the following grammar :
S: NP VP
PP: P NP
NP: Det N | Det N PP | 'I'
VP: V NP | VP PP
V: 'shot' | 'killed' | 'wounded'
Det: 'an' | 'my'
N: 'elephant' | 'pajamas' | 'cat' | 'dog'
P: 'in' | 'outside'
It works great. Some examples :
my pajamas killed my elephant
an pajamas wounded my pajamas in my pajamas
an dog in I wounded my cat in I outside my elephant in my elephant in an pajamas outside an cat
I wounded my pajamas in my dog
This grammar has a recursion (PP: P NP > NP: Det N PP). When I take this other recursive grammar, for math expression this time :
expr: term (('+' | '-') term)*
term: fact (('*' | '/') fact)*
fact: '1' | '(' expr ')'
Almost one time in two, I get a "Maximum call stack size exceeded" error (in NodeJS). The other half of the time, I get correct expressions :
( 1 ) * 1 + 1
( ( 1 ) / ( 1 + 1 ) - ( 1 / ( 1 * 1 ) ) / ( 1 / 1 - 1 ) ) * 1
( ( ( 1 ) ) )
1
1 / 1
I guess the recursive production for fact gets called too often, too deep in the call stack and this makes the whole thing just blow off.
How can I make my approach less naive in order to avoid those cases that explode the call stack ? Thank you.
Of course if a grammar describes arbitrarily long inputs, you can easily end up in a very deep recursion. A simple way to avoid this trap is keep a priority queue of partially expanded sentential forms where the key is length. Remove the shortest and replace each non-terminal in each possible way, emitting those that are now all terminals and adding the rest back onto the queue. You might also want to maintain an "already emitted" set to avoid emitting duplicates. If the grammar doesn't have anything like epsilon productions where a sentential form derives a shorter string, then this method produces all strings described by the grammar in non-decreasing length order. That is, once you've seen an output of length N, all strings of length N-1 and shorter have already appeared.
Since OP asked about details, here's an implementation for the expression grammar. It's simplified by rewriting the PEG as a CFG.
import heapq
def run():
g = {
'<expr>': [
['<term>'],
['<term>', '+', '<expr>'],
['<term>', '-', '<expr>'],
],
'<term>': [
['<fact>'],
['<fact>', '*', '<term>'],
['<fact>', '/', '<term>'],
],
'<fact>': [
['1'],
['(', '<expr>', ')']
],
}
gen(g)
def is_terminal(s):
for sym in s:
if sym.startswith('<'):
return False;
return True;
def gen(g, lim = 10000):
q = [(1, ['<expr>'])]
n = 0;
while n < lim:
_, s = heapq.heappop(q)
# print("pop: " + ''.join(s))
a = []
b = s.copy()
while b:
sym = b.pop(0)
if sym.startswith('<'):
for rhs in g[sym]:
s_new = a.copy()
s_new.extend(rhs)
s_new.extend(b)
if is_terminal(s_new):
print(''.join(s_new))
n += 1
else:
# print("push: " + ''.join(s_new))
heapq.heappush(q, (len(s_new), s_new))
break # only generate leftmost derivations
a.append(sym)
run()
Uncomment the extra print()s to see heap activity. Some example output:
1
(1)
1*1
1/1
1+1
1-1
((1))
(1*1)
(1/1)
(1)*1
(1)+1
(1)-1
(1)/1
(1+1)
(1-1)
1*(1)
1*1*1
1*1/1
1+(1)
1+1*1
1+1/1
1+1+1
1+1-1
1-(1)
1-1*1
1-1/1
1-1+1
1-1-1
1/(1)
1/1*1
1/1/1
1*1+1
1*1-1
1/1+1
1/1-1
(((1)))
((1*1))
((1/1))
((1))*1
((1))+1
((1))-1
((1))/1
((1)*1)
((1)+1)
((1)-1)
((1)/1)
((1+1))
((1-1))
(1)*(1)
(1)*1*1
(1)*1/1
(1)+(1)
(1)+1*1
Corrects sequences of parentesis can be defined recursively:
The empty string "" is a correct sequence.
If "X" and "Y" are correct sequences, then "XY" (the concatenation of
X and Y) is a correct sequence.
If "X" is a correct sequence, then "(X)" is a correct sequence.
Each correct parentheses sequence can be derived using the above
rules.
Given two strings s1 and s2. Each character in these strings is a parenthesis, but the strings themselves are not necessarily correct sequences of parentheses.
You would like to interleave the two sequences so that they will form a correct parentheses sequence. Note that sometimes two different ways of interleaving the two sequences will produce the same final sequence of characters. Even if that happens, we count each of the ways separately.
Compute and return the number of different ways to produce a correct parentheses sequence, modulo 10^9 + 7.
Example s1 = (() and s2 = ())
corrects sequences of parentheses, s1 (red) and s2(blue)
I don't understand the recursive algorithm, what does X and Y mean? And modulo 10^9 + 7?
First, I tried defining all permutations of s1 and s2 and then calculate the number of balanced parentheses. But that way is wrong, isn't it?
class InterleavingParenthesis:
def countWays(self, s1, s2):
sequences = list(self.__exchange(list(s1 + s2)))
corrects = 0
for sequence in sequences:
if self.__isCorrect(sequence):
corrects += 1
def __isCorrect(self, sequence):
s = Stack()
balanced = True
i = 0
while i < len(sequence) and balanced:
if '(' == sequence[i]:
s.stack(sequence[i])
elif s.isEmpty():
balanced = False
else: s.remove()
i += 1
if s.isEmpty() and balanced: return True
else: return False
def __exchange(self, s):
if len(s) <= 0: yield s
else:
for i in range(len(s)):
for p in self.__exchange(s[:i] + s[i + 1:]):
yield [s[i]] + p
class Stack:
def __init__(self):
self.items = []
def stack(self, data):
self.items.append(data)
def remove(self):
self.items.pop()
def isEmpty(self):
return self.items == []
Here's an example that shows how this recursive property works:
Start with:
X = "()()(())"
Through property 2, we break this into further X and Y:
X = "()" ; Y = "()(())"
For X, we can look at the insides with property 3.
X = ""
Because of property 1, we know this is valid.
For Y, we use property 2 again:
X = "()"
Y = "(())"
Using the same recursion as before (property 2, then property 1) we know that X is valid. Note that in code, you usually have to go through the same process, I'm just saving time for humans. For Y, you use property 3:
X = "()"
And again.. :
X = ""
And with property 1, you know this is valid.
Because all sub-parts of "()()(())" are valid, "()()(())" is valid. That's an example of recursion: You keep breaking things down into smaller problems until they are solvable. In code, you would have the function call itself with regards to a smaller part of it, in your case, X and Y.
As for the question you were given, there is a bit that doesn't make sense to me. I don't get how there is any room for doubt in any string of parentheses, like in the image you linked. In "((()())())" for example, there is no way these two parentheses do not match up: "((()())())". Therefore my answer would be that there is only one permutation for every valid string of parentheses, but this obviously is wrong somehow.
Could you or anyone else expand on this?
In F# im trying to remove an occurence in the set if a condition is met, however it's not really working they way i'd like it to.
The trick to removing elements from a set is the function Set.filter, which takes a function as an argument - filter will feed in every value of the set to your function, and add it to a new set if the function returns true. An example implementation might be:
let filter f (original : Set<'T>) =
set [ for value in original do if f value then yield value ]
which has type filter : ('T -> bool) -> Set<'T> -> Set<'T>. An example of using it would be
filter (fun x -> x % 2 = 0) (set [ 1; 2; 3; 4; 5 ])
This filters the set for even numbers, so the return value would be set [ 2; 4 ].
I'm not entirely sure what problem you're having exactly, but here is a solution to the game Mastermind using Knuth's algorithm, albeit with a random starting guess, rather than his choice of "1122".
I thought it was quite a nice exercise, though writing the checkGuess function was the hardest part of it for me!
You can run a test by opening this in F# interactive by running the function playMastermind (), which will show you its guesses.
/// The colours that pegs are allowed to be.
type Peg = Blue | Red | Green | Yellow | Purple | Brown
/// A shared instance of the System.Random () class for all the random number
/// generators.
let private rnd = new System.Random ()
/// Make a random set of four peg colours.
let randomGuess () =
let randomPeg () =
match rnd.Next(1, 6) with
| 1 -> Blue
| 2 -> Red
| 3 -> Green
| 4 -> Yellow
| 5 -> Purple
| 6 -> Brown
| _ -> failwith "Random number generation failed."
[ randomPeg (); randomPeg (); randomPeg (); randomPeg () ]
/// Iterate over the colours to make all of the possible combinations.
let allPossibles =
let colours = [ Blue; Red; Green; Yellow; Purple; Brown]
set [ for a in colours do for b in colours do for c in colours do for d in colours -> [ a; b; c; d ] ]
/// Get the number of white and black pegs when comparing solution to guess.
let checkGuess solution guess =
/// Create a map of (colour -> count).
let toMap = List.countBy id >> Map.ofList
/// Compute how many pegs' colours are shared in the guesses.
let mapIntersect map1 map2 =
let overlap peg count =
match Map.tryFind peg map2 with
| None -> 0
| Some num -> min num count
Map.fold (fun acc peg count -> acc + overlap peg count) 0 map1
/// Simply compare to see if each peg is in the correct place.
let blacks = List.map2 (fun x y -> if x = y then 1 else 0) solution guess |> List.sum
// The number of pegs of the right colour but the wrong location is the
// same as the total number of pegs of the right colour subtract the ones
// that are also in the right place.
let whites = mapIntersect (toMap solution) (toMap guess) - blacks
whites, blacks
/// Get a random element of a set.
let randomSetElement set =
let arr = Set.toArray set
arr.[rnd.Next (Array.length arr)]
let playMastermind () =
// This creates a closure so we can check our guess against the solution,
// without storing the actual value of the solution.
let checkAnswer = checkGuess (randomGuess ())
let rec loop turnCount remaining =
if Set.count remaining = 1 then
let answer = Set.maxElement remaining
printfn "The answer is %A, which I calculated in %d turns." answer (turnCount - 1)
else
let guess = randomSetElement remaining
let (whites, blacks) = checkAnswer guess
printfn "On turn %d I guessed %A, which gave %d white pins and %d black pins." turnCount guess whites blacks
/// Remove all possibilities from the solution that wouldn't give the
/// same numbers of white and black pins and continue.
loop (turnCount + 1) (Set.filter (fun possible -> (whites, blacks) = checkGuess possible guess) remaining)
// Play the game!
loop 1 allPossibles
I'd make this a comment, but it's too long, so it needs to be an answer instead, even though it's not a complete answer to your problem.
One problem with your code, as it is now, is this section:
for candidate in candidateSet do
let scString = candidate.ToString()
let mutable secretList = []
for i = 0 to 3 do
let digit = (int scString.[i])-(int '0')
secretList <- secretList # [digit]
let tempCode = List.map (fun x -> numberToCodeColorPlus (x)) secretList
//Validate works and returns a peg set (b,w)..e.g. (0,0)
let secretCodePegs = validate guess tempCode
if secretCodePegs <> guessPegs then
candidateSet <- Set.remove candidate candidateSet
F#, like Python, uses indentation to denote blocks. So that let secretCodePegs = validate guess tempCode line is outside the for loop, not inside the for loop the way you clearly intended it to be. And the if secretCodePegs <> guessPegs then line that follows it, as far as F# is concerned, is part of a new block, and not part of the for loop any longer (because the let secretCodePegs = ... line ended the for loop). All you need to do is indent the let secretCodePegs = ... line by one level, and your code will work. In other words, that section should have looked like this:
for candidate in candidateSet do
let scString = candidate.ToString()
let mutable secretList = []
for i = 0 to 3 do
let digit = (int scString.[i])-(int '0')
secretList <- secretList # [digit]
let tempCode = List.map (fun x -> numberToCodeColorPlus (x)) secretList
//Validate works and returns a peg set (b,w)..e.g. (0,0)
let secretCodePegs = validate guess tempCode
if secretCodePegs <> guessPegs then
candidateSet <- Set.remove candidate candidateSet
I am trying to create a Hashtable in OCaml in O(n) time (n being the length of a string).
Here is my code:
let fill_table set my_hash =
for i = 0 to ((String.length set) - 1) do
Hashtbl.add my_hash (Char.code set.[i]) (set.[i])
done
;;
where set is a string (ex/ "12345") and my_hash is previously initiated as:
let my_hash = Hashtbl.create 255 (* Highest ASCII number possible *)
Does 'fill_table' function run in O(n) time? Please let me know. Thanks!
Since your table never exceeds around 255 entries, you can reasonably consider the time as being linear in the length of the string.
However, you should realize that if you add a new mapping for an old value to an OCaml hash table, it keeps both entries in the table. This is strange, but OCaml hash tables have always worked this way. You might want to check whether you have an entry in the table before bothering to add a new one.
# let h = Hashtbl.create 255;;
val h : ('_a, '_b) Hashtbl.t = <abstr>
# Hashtbl.add h 32 ' ';;
- : unit = ()
# Hashtbl.add h 32 ' ';;
- : unit = ()
# Hashtbl.iter (fun k v -> Printf.printf "saw %d\n" k) h;;
saw 32
saw 32
- : unit = ()
As a side comment, I don't see much reason to map from the character code to the character. You can get this without a hash table using Char.chr.