I am trying to solve the Leetcode "Reverse Integer" challenge in python.
I took look at the solution they supplied.
Their answer was written in Java.
I do not know why they use the following test-condition:
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
I wrote my python code without that same test condition.
It failed when I tested a negative number.
class Solution:
def reverse(self, x: int) -> int:
rev = 0
while( x != 0 ):
pop = x % 10
x //= 10
rev = rev * 10 +pop
print(rev)
return rev
I do not understand why that particular test-condition exists in their code.
The goal is to reverse the order of digits in an integer.
Some examples are shown below:
Example 1:
Input: x = 123
Output: 321
Example 2:
Input: x = -123
Output: -321
Example 3:
Input: x = 120
Output: 21
Example 4:
Input: x = 0
Output: 0
class Solution {
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
}
Branch conditions are sometimes easier to understand when they are drawn as tree-diagrams instead of one line formulas.
Also, we can write the tree like this:
├── OR
│ ├── (rev > Integer.MAX_VALUE/10)
│ └── AND
│ ├── rev == Integer.MAX_VALUE / 10
│ └── pop > 7
Imagine that rev is a container, like a cookie-jar, or a carboard box.
There is a maximum number of cookies which can be crammed into the cookie jar.
When rev == Integer.MAX_VALUE it means that the cookie jar is full.
The condition rev == Integer.MAX_VALUE/ 10 is represent the idea that the cookie-jar can only fit one more cookie.
Instead of stuffing cookies into cookie jars, we are stuffing digits (such as 5) into an integer.
The integer is the container.
Note that when you append zero to an integer in base 10, it is the same as multiplying by 10. For example, 25 becomes 250
Suppose that the largest integer allowed is 2,147,483,647
Note that 214,748,364 is equal to 2,147,483,647 / 10
When you divide by 10, the decimal part of the number is discarded.
When rev is 214,748,364, then you can append any integer the right-most end, as long as that digit is less than or equal to 7.
Old Element
New Element
New Container
Status
214748364
0
2147483640
VALID
214748364
1
2147483641
VALID
214748364
2
2147483642
VALID
214748364
3
2147483643
VALID
214748364
4
2147483644
VALID
214748364
5
2147483645
VALID
214748364
6
2147483646
VALID
214748364
7
2147483647
VALID
214748364
8
2147483648
TOO BIG
214748364
9
2147483649
TOO BIG
The "status" column in the table above
In their code, when they wrote (pop > 7) it probably should have been (pop > Integer.MAX_VALUE % 10)
Suppose that the largest integer allowed is 2,147,483,647
Then, 2,147,483,647 % 10 is equal to 7.
There are many, many different ways to reverse the digits of a number.
One solution, in python, is shown below:
x = int(reversed(str(x)))
I would like to solve the following lock challenge using Alloy.
My main issue is how to model the integers representing the digit keys.
I created a quick draft:
sig Digit, Position{}
sig Lock {
d: Digit one -> lone Position
}
run {} for exactly 1 Lock, exactly 3 Position, 10 Digit
In this context, could you please:
tell me if Alloy seems to you suitable to solve this kind of problem?
give me some pointers regarding the way I could model the key digits (without using Ints)?
Thank you.
My frame of this puzzle is:
enum Digit { N0,N1,N2,N3,N4,N5,N6,N7,N8,N9 }
one sig Code {a,b,c:Digit}
pred hint(h1,h2,h3:Digit, matched,wellPlaced:Int) {
matched = #(XXXX) // fix XXXX
wellPlaced = #(XXXX) // fix XXXX
}
fact {
hint[N6,N8,N2, 1,1]
hint[N6,N1,N4, 1,0]
hint[N2,N0,N6, 2,0]
hint[N7,N3,N8, 0,0]
hint[N7,N8,N0, 1,0]
}
run {}
A simple way to get started, you do not always need sig's. The solution found is probably not the intended solution but that is because the requirements are ambiguous, took a shortcut.
pred lock[ a,b,c : Int ] {
a=6 || b=8 || c= 2
a in 1+4 || b in 6+4 || c in 6+1
a in 0+6 || b in 2+6 || c in 2+0
a != 7 && b != 3 && c != 8
a = 7 || b=8 || c=0
}
run lock for 6 int
Look in the Text view for the answer.
upate we had a discussion on the Alloy list and I'd like to amend my solution with a more readable version:
let sq[a,b,c] = 0->a + 1->b + 2->c
let digit = { n : Int | n>=0 and n <10 }
fun correct[ lck : seq digit, a, b, c : digit ] : Int { # (Int.lck & (a+b+c)) }
fun wellPlaced[ lck : seq digit, a, b, c : digit ] : Int { # (lck & sq[a,b,c]) }
pred lock[ a, b, c : digit ] {
let lck = sq[a,b,c] {
1 = correct[ lck, 6,8,2] and 1 = wellPlaced[ lck, 6,8,2]
1 = correct[ lck, 6,1,4] and 0 = wellPlaced[ lck, 6,1,4]
2 = correct[ lck, 2,0,6] and 0 = wellPlaced[ lck, 2,0,6]
0 = correct[ lck, 7,3,8]
1 = correct[ lck, 7,8,0] and 0 = wellPlaced[ lck, 7,8,0]
}
}
run lock for 6 Int
When you think solve complete, let's examine whether the solution is generic.
Here is another lock.
If you can’t solve this in same form, your solution may not enough.
Hint1: (1,2,3) - Nothing is correct.
Hint2: (4,5,6) - Nothing is correct.
Hint3: (7,8,9) - One number is correct but wrong placed.
Hint4: (9,0,0) - All numbers are correct, with one well placed.
Yes, I think Alloy is suitable for this kind of problem.
Regarding digits, you don't need integers at all: in fact, it is a bit irrelevant for this particular purpose if they are digits or any set of 10 different identifiers (no arithmetic is performed with them). You can use singleton signatures to declare the digits, all extending signature Digit, which should be marked as abstract. Something like:
abstract sig Digit {}
one sig Zero, One, ..., Nine extends Digit {}
A similar strategy can be used to declare the three different positions of the lock. And btw since you have exactly one lock you can also declare Lock as singleton signature.
I like the Nomura solution on this page. I made a slight modification of the predicate and the fact to solve.
enum Digit { N0,N1,N2,N3,N4,N5,N6,N7,N8,N9 }
one sig Code {a,b,c: Digit}
pred hint(code: Code, d1,d2,d3: Digit, correct, wellPlaced:Int) {
correct = #((code.a + code.b + code.c)&(d1 + d2 + d3))
wellPlaced = #((0->code.a + 1->code.b + 2->code.c)&(0->d1 + 1->d2 + 2->d3))
}
fact {
some code: Code |
hint[code, N6,N8,N2, 1,1] and
hint[code, N6,N1,N4, 1,0] and
hint[code, N2,N0,N6, 2,0] and
hint[code, N7,N3,N8, 0,0] and
hint[code, N7,N8,N0, 1,0]
}
run {}
Update (2020-12-29):
The new puzzle presented by Nomura (https://stackoverflow.com/a/61022419/5005552) demonstrates a weakness in the original solution: it does not account for multiple uses of a digit within a code. A modification to the expression for "correct" fixes this. Intersect each guessed digit with the union of the digits from the passed code and sum them for the true cardinality. I encapsulated the matching in a function, which will return 0 or 1 for each digit.
enum Digit {N0,N1,N2,N3,N4,N5,N6,N7,N8,N9}
let sequence[a,b,c] = 0->a + 1->b + 2->c
one sig Code {c1, c2, c3: Digit}
fun match[code: Code, d: Digit]: Int { #((code.c1 + code.c2 + code.c3) & d) }
pred hint(code: Code, d1,d2,d3: Digit, correct, wellPlaced:Int) {
// The intersection of each guessed digit with the code (unordered) tells us
// whether any of the digits match each other and how many
correct = match[code,d1].plus[match[code,d2]].plus[match[code,d3]]
// The intersection of the sequences of digits (ordered) tells us whether
// any of the digits are correct AND in the right place in the sequence
wellPlaced = #(sequence[code.c1,code.c2,code.c3] & sequence[d1, d2, d3])
}
pred originalLock {
some code: Code |
hint[code, N6,N8,N2, 1,1] and
hint[code, N6,N1,N4, 1,0] and
hint[code, N2,N0,N6, 2,0] and
hint[code, N7,N3,N8, 0,0] and
hint[code, N7,N8,N0, 1,0]
}
pred newLock {
some code: Code |
hint[code, N1,N2,N3, 0,0] and
hint[code, N4,N5,N6, 0,0] and
hint[code, N7,N8,N9, 1,0] and
hint[code, N9,N0,N0, 3,1]
}
run originalLock
run newLock
run test {some code: Code | hint[code, N9,N0,N0, 3,1]}
I have a class named Vowels which contains 5 variables representing each vowel. User inputs a sentence, some voodoo magic happens and a method counts the vowels a prints them:
[a = 9, e = 5, i = 7, o = 5, u = 6]
After that the user is requested to input a random integer and another method does all 4 basic math operations as below:
input
3
output
a --> 9 * 3 = 27
a --> 9 / 3 = 3
a --> 9 + 3 = 12
a --> 9 - 3 = 6
So far I have managed to make this happen with 20 printlns (1 for each operation for each vowel), but could this be somehow optimized with a loop?
I found some info about reflection, but I don't really understand it.
The members of your object are available by calling getProperties. Every object has a property named class, which you can ignore, and the order is not defined, so 'e' might appear in the properties before 'a'. Example:
class Vowels {
int a, e, i, o, u
}
def v = new Vowels(a: 9, e: 5, i: 7, o: 5, u: 6)
v.properties.each { name, value ->
if (name != 'class') {
println "$name --> $value * 3 == ${value * 3}"
...
}
}