Lower Limit < A < Upper Limit - swift

I need to know if something is between two limits, but I keep getting the same 2 errors in playground and I can't seem to find a solution on the web. Any idea how to do this in Swift?
var upperLimit = 20
var a = 10
var lowerlimit = 5
if a > lowerlimit < upperLimit{
println(a)
}
if lowerlimit < a < upperLimit{
println(a)
}
Both of these methods give the same (2) error messages:
---> ! Non-associative operator is adjacent to operator of same precedence
--> Cannot invoke '<'with an argument of list type '($t4, #Ivalue Int)'

That's not a valid way to make the comparison. You need to check against the bounds with two comparisons:
if a > lowerlimit && a < upperLimit {
println(a)
}
Although I prefer this way using pattern recognition on a range.
if lowerlimit..<upperLimit ~= a {
println(a)
}
Note that the pattern recognition way requires the lower bound to be inclusive, so you'd need to increase the lowerLimit variable by one.

Related

What does the error mean "Cannot convert value of type"?

The Python code was taken as a basis: enter link description here
Errors occur in each cycle
A lot of errors (please help fix it):
enter image description here
Code:
var t = readLine()!
var s = readLine()!
var len_s = s.count
var t_lis = Set(t)
let character:[Character] = Array(s)
var c_s:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character, Array(repeating: 1, count: character.count)))
let character2:[Character] = Array(t_lis)
var c_t:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character2, Array(repeating: 1, count: character2.count)))
var c_res = [String: String]()
var summ = 0
for e in c_s{
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
summ += c_res[e][1]}
for i in 0..<((t.count-s.count)+1) {
if summ == len_s-1{
print(i)
break
}
for j in c_res{
if t[i] = c_res[j]{
if c_res[t[i]][1] > 0{
c_res[t[i]][1] -= 1
summ -= 1
}}}
for l in c_res {
if (i+len_s < t.count && t[i+len_s]) = c_res{
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]{
c_res[ t[i+len_s] ][1] += 1
summ += 1
}}}
}
For reference, here is the original Python code that OP linked to:
t = input('t = ')
s = input('s = ')
len_s = len(s)
t_lis = list(t)
c_s = Counter(s)
c_t = Counter(t_lis[:len_s])
c_res = dict()
summ = 0
for e in c_s:
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
summ += c_res[e][1]
for i in range( len(t)-len(s)+1 ):
if summ == len_s-1:
print(i)
break
if t[i] in c_res:
if c_res[t[i]][1] > 0:
c_res[t[i]][1] -= 1
summ -= 1
if i+len_s < len(t) and t[i+len_s] in c_res:
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]:
c_res[ t[i+len_s] ][1] += 1
summ += 1
else:
print(-1)
First I want to mention that the Python code that was linked to is pretty bad. By that, I mean that nothing is clearly named. It's totally obtuse as to what it's trying to accomplish. I'm sure it would be clearer if I spoke Russian or whatever the languge on that page is, but it's not either of the ones I speak. I know Python programming has a different culture around it than Swift programming since Python is often written for ad hoc solutions, but it really should be refactored, with portions extracted into well-named functions. That would make it a lot more readable, and might have helped you in your translation of it into Swift. I won't try to do those refactorings here, but once the errors are fixed, if you want to use it in any kind of production environment, you really should clean it up.
As you acknowledge, you have a lot of errors. You ask what the errors mean, but presumably you want to know how to fix the problems, so I'll address both. The errors start on this line:
c_res[e] = [c_s[e], min( c_s[e], c_t[e] )]
The first error is Cannot assign value of type '[Any]' to subscript of type 'String'
This means you are building an array containing elements of type Any and trying to assign it to c_res[e]. c_res is Dictionary with keys of type String and values of type String. So assuming e were a String, which it isn't - more on that in a sec - then c_res[e] would have the type of the value, a String.
The natural question would be why is the right-hand side an array of Any. It comes down to the definition of the array isn't legal, and the compiler is choking on it (basically, a by-product of other errors). The reason is because min expects all of its parameters to be of a single type that conforms to the Comparable protocol, but c_s[e] and c_s[e] are illegal... and that's because they are both Dictionary<Character, Int>, so they expect an index of type of Character, but e isn't a Character. It's a tuple, (Character, Int). The reason is to be found on the preceding line:
for e in c_s{
Since c_s is Dictionary<Character, Int> it's elements are tuples containing a Character and an Int. That might be surprising for a Python programmer new to Swift. To iterate over the keys you have to specify that's what you want, so let's correct that:
for e in c_s.keys {
With that fixed, previous errors go away, but a new problem is exposed. When you index into a Dictionary in Swift you get an optional value, because it might be nil if there is no value stored for that key, so it needs to be unwrapped. If you're sure that neither c_s[e] nor c_t[e] will be nil you could force-unwrap them like this:
c_res[e] = [c_s[e]!, min( c_s[e]!, c_t[e]! )]
But are you sure? It's certainly not obvious that they must be. So we need to handle the optional, either with optional binding, or optional coallescing to provide a default value if it is nil.`
for (e, csValue) in c_s {
let ctValue = c_t[e] ?? Int.max
c_res[e] = [csValue, min(csValue, ctValue]
summ += c_res[e][1]
}
Note that we've gone back to iterating over c_s instead of c_s.keys, but now we're using tuple binding to assign just the key to e and the value to csValue. This avoids optional handing for c_s elements. For the value from c_t[e] I use optional coallescing to default it to the maximum integer, that way if c_t[e] is nil, min will still return csValue which seems to be the intent.
But again we have exposed another problem. Now the compiler complains that we can't assign Array<Int> to c_res[e] which is expected to be a String... In Swift, String is not an Array<Int>. I'm not sure why c_res is defined to have values of type String when the code puts arrays of Int in it... so let's redefine c_res.
var c_res = [String: [Int]]()
var summ = 0
for (e, csValue) in c_s {
let ctValue = c_t[e] ?? Int.max
c_res[e] = [csValue, min(csValue, ctValue)]
summ += c_res[e][1]
To paraphrase a Nirvana lyric, "Hey! Wait! There is a new complaint!" Specifically, e is type Character, but c_res is Dictionary<String, Array<Int>>, so let's just make c_res a Dictionary<Character, Array<Int>> instead.
var c_res = [Character: [Int]]()
var summ = 0
for (e, csValue) in c_s {
let ctValue = c_t[e] ?? Int.max
c_res[e] = [csValue, min(csValue, ctValue)]
summ += c_res[e][1]
}
Yay! Now we've resolved all the errors on the line we started with... but there's now one on the next line: Value of optional type '[Int]?' must be unwrapped to refer to member 'subscript' of wrapped base type '[Int]'
Again this is because when we index into a Dictionary, the value for our key might not exist. But we just computed the value we want to add to summ in our call to min, so let's save that off and reuse it here.
var c_res = [Character: [Int]]()
var summ = 0
for (e, csValue) in c_s {
let ctValue = c_t[e] ?? Int.max
let minC = min(csValue, ctValue)
c_res[e] = [csValue, minC]
summ += minC
}
Now we finally have no errors in the first loop. Remaining errors are in the nested loops.
For starters, the code uses = to test for equality. As with all languages in the C family, Swift uses == as the equality operator. I think that change, which is needed in couple of places, is pretty straight forward, so I won't show that iteration. Once those are fixed, we get one of my favorite (not) errors in Swift: Type of expression is ambiguous without more context on this line:
if t[i] == c_res[j] {
These ambiguity errors can mean one of a few things. The main reason is because elements of the expression match several definitions, and the compiler doesn't have a way to figure out which one should be used. That flavor is often accompanied by references to the possible matches. It also seems to happen when multiple type-check failures combine in a way the compiler can't give a clearer error. I think that's the version that's happening here. The source of this problem goes back to the outer loop
for i in 0..<((t.count-s.count)+1) {
which makes the loop variable, i, be of type, Int, combined with using i to index into t, which is a String. The problem is that you can't index into String with an Int. You have to use String.Index. The reason comes down to String consisting of unicode characters and using UTF-8 internally, which means that it's characters are of different lengths. Indexing with an Int in the same way as you would for an element of an Array would require O(n) complexity, but indexing into a String is expected to have O(1) complexity. String.Index solves this by using String methods like index(after:) to compute indices from other indices. Basically indexing into a String is kind of pain, so in most cases Swift programmers do something else, usually relying on the many methods String supports to manipulate it. As I'm writing this, I haven't yet put together what the code is supposed to be doing, which makes it hard to figure out what String methods might be helpful here, so let's just convert t to Array[Character], then we can use integers to index into it:
var t = [Character](readLine()!)
That still gives an ambiguous expression error though, so I looked at the equivalent line in the Python code. This revealed a logic error in translation. Here's the Python:
if t[i] in c_res:
if c_res[t[i]][1] > 0:
c_res[t[i]][1] -= 1
summ -= 1
There is no loop. It looks like the loop was introduced to mimic the check to see if t[i] is in c_res, which is one way to do it, but it was done incorrectly. Swift has a way to do that more succinctly:
if c_res.keys.contains(t[i]) {
if c_res[t[i]][1] > 0 {
c_res[t[i]][1] -= 1
summ -= 1
}
}
But we can use optional binding to clean that up further:
let tChar = t[i]
if let cResValue = c_res[tChar] {
if cResValue[1] > 0 {
c_res[tChar][1] -= 1
summ -= 1
}
}
But again we have the problem of indexing into a Dictionary returning an optional which needs unwrapping on the line,
c_res[tChar][1] -= 1
Fortunately we just ensured that c_res[tChar] exists when we bound it to cResValue, and the only reason we need to index into again is because we need to update the dictionary value... this is a good use of a force-unwrap:
let tChar = t[i]
if let cResValue = c_res[tChar] {
if cResValue[1] > 0 {
c_res[tChar]![1] -= 1
summ -= 1
}
}
The last loop also seems to be the result of testing for existence in c_res and the loop variable isn't even used. Here's the original Python:
if i+len_s < len(t) and t[i+len_s] in c_res:
if c_res[ t[i+len_s] ][1] < c_res[ t[i+len_s] ][0]:
c_res[ t[i+len_s] ][1] += 1
summ += 1
We can use optional binding here combined with the comma-if syntax, and another force-unwrap.
tChar = t[i + len_s]
if i+len_s < t.count, let cResValue = c_res[tChar] {
if cResValue[1] < cResValue[0] {
c_res[tChar]![1] += 1
summ += 1
}
}
Of course, since we're re-using tChar with a new value, it has to be changed from let to var.
Now it all compiles. It definitely needs refactoring, but here it is altogether:
import Foundation
var t = [Character](readLine()!)
var s = readLine()!
var len_s = s.count
var t_lis = Set(t)
let character:[Character] = Array(s)
var c_s:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character, Array(repeating: 1, count: character.count)))
let character2:[Character] = Array(t_lis)
var c_t:[Character: Int] = Dictionary(uniqueKeysWithValues: zip(character2, Array(repeating: 1, count: character2.count)))
var c_res = [Character: [Int]]()
var summ = 0
for (e, csValue) in c_s {
let ctValue = c_t[e] ?? Int.max
let minC = min(csValue, ctValue)
c_res[e] = [csValue, minC]
summ += minC
}
for i in 0..<((t.count-s.count)+1) {
if summ == len_s-1 {
print(i)
break
}
var tChar = t[i]
if let cResValue = c_res[tChar] {
if cResValue[1] > 0 {
c_res[tChar]![1] -= 1
summ -= 1
}
}
tChar = t[i + len_s]
if i+len_s < t.count, let cResValue = c_res[tChar] {
if cResValue[1] < cResValue[0] {
c_res[tChar]![1] += 1
summ += 1
}
}
}
If all of this makes you wonder why anyone would use such a picky language, there are two things to consider. The first is that you don't get so many errors when writing code originally in Swift, or even when translating from another strongly typed language. Coverting from a typeless language, like Python, is a problem, because apart from subtle other differences, you also have to pin down it's overly flexible view of data to some concrete type - and that's not always obvious how to do it. The other thing is that strongly typed languages allow you to catch huge classes of bugs early... because the type system won't even let them compile.

Are overflow operators less efficient than performing operations that don't result in overflows?

What I Am Doing: I am writing a chess engine in Swift. One of the most important parts of writing a strong chess engine is the ability to generate as many possible future board positions in as little time possible. The more positions your engine can generate and evaluate in a shorter amount of time, the stronger the engine is.
That being said, I've written functions for generating moves for sliding pieces (bishops, rooks, and queens). These functions make use of overflow operators (&+, &-, &*), as using normal bitwise operators frequently cause overflow errors.
Generating said moves requires two functions, one for generating all legal vertical and horizontal moves for a sliding piece, and one for generating all legal diagonal moves for a sliding piece. These two functions effectively go about doing the same thing, we just manipulate the arguments slightly differently. Here is what the function for generating horizontal and vertical moves looks like:
//occupied is a bitboard that represents every square on the chess board that is occupied
//this value is set somewhere before our move generation functions are ever called
var occupied: UInt64 = 0
//the rankMasks and fileMasks are simply arrays of bitboards that represent each individual file and rank on a chess board
//rankMasks8[0] would represent the squares a8-h8, rankMasks8[1] would represent the squares a7-h7
//fileMasks8[0] would represent the squares a1-a8, fileMasks8[1] would represent the squares b1-b8
let rankMasks8: [UInt64] = [ 255, 65280, 16711680, 4278190080, 1095216660480, 280375465082880, 71776119061217280, 18374686479671623680 ]
let fileMasks8: [UInt64] = [ 72340172838076673, 144680345676153346, 289360691352306692, 578721382704613384, 1157442765409226768, 2314885530818453536, 4629771061636907072, 9259542123273814144 ]
...
//We pass a square (0 - 63) as s and we are returned a UInt64, the bitboard representing all the squares that the piece on the passed square can move to.
func horizontalAndVerticalMoves(s: Int) -> UInt64 {
//convert the passed square into a bitboard that represents its location, by raising 2 to the power of s
let binaryS: UInt64 = 1<<s
//formula for generating possible horizontal moves
let possibilitiesHorizontal: UInt64 = (occupied &- (2 &* binaryS)) ^ UInt64.reverse(UInt64.reverse(occupied) &- 2 &* UInt64.reverse(binaryS))
//formula for generating vertical moves
let possibilitiesVertical: UInt64 = ((occupied & fileMasks8[s % 8]) &- (2 &* binaryS)) ^ UInt64.reverse(UInt64.reverse(occupied & fileMasks8[s % 8]) &- (2 &* UInt64.reverse(binaryS)))
//we return possible horizontal moves OR possible vertical moves
return (possibilitiesHorizontal & rankMasks8[s / 8]) | (possibilitiesVertical & fileMasks8[s % 8])
}
The only important thing you need to recognize about the above function is that it gives us the expected output and it does so using overflow operators.
Now, my previous iteration of this same method (before I understood how to circumvent the overflows using overflow operators) was much more drawn out. It required running four while loops that would move away from the current piece in either the "north", "south", "east", or "west" direction until it came into contact with a piece that blocks further movement in the respective direction. Here's what this iteration of the horizontalAndVerticalMoves function looked like:
func horizontalAndVerticalMoves(s: Int) -> UInt64 {
let rankMask: UInt64 = rankMasks8[s/8]
let fileMask: UInt64 = fileMasks8[s%8]
let pseudoPossibleMoves: UInt64 = rankMask ^ fileMask
var unblockedRanks: UInt64 = 0
var unblockedFiles: UInt64 = 0
var direction: Direction! = Direction.north
var testingSquare: Int = s - 8
while direction == .north {
if testingSquare < 0 || testingSquare%8 != s%8 {
direction = .east
} else {
if 1<<testingSquare&occupied != 0 {
unblockedRanks += rankMasks8[testingSquare/8]
direction = .east
} else {
unblockedRanks += rankMasks8[testingSquare/8]
testingSquare -= 8
}
}
}
testingSquare = s + 1
while direction == .east {
if testingSquare > 63 || testingSquare/8 != s/8 {
direction = .south
} else {
if 1<<testingSquare&occupied != 0 {
unblockedFiles += fileMasks8[testingSquare%8]
direction = .south
} else {
unblockedFiles += fileMasks8[testingSquare%8]
testingSquare += 1
}
}
}
testingSquare = s + 8
while direction == .south {
if testingSquare > 63 || testingSquare%8 != s%8 {
direction = .west
} else {
if 1<<testingSquare&occupied != 0 {
unblockedRanks += rankMasks8[testingSquare/8]
direction = .west
} else {
unblockedRanks += rankMasks8[testingSquare/8]
testingSquare += 8
}
}
}
testingSquare = s - 1
while direction == .west {
if testingSquare < 0 || testingSquare/8 != s/8 {
direction = .north
} else {
if 1<<testingSquare&occupied != 0 {
unblockedFiles += fileMasks8[testingSquare%8]
direction = .north
} else {
unblockedFiles += fileMasks8[testingSquare%8]
testingSquare -= 1
}
}
}
let mask = unblockedRanks | unblockedFiles
let possibleMoves = pseudoPossibleMoves&mask
return possibleMoves
}
I figured my newly implemented version of this function (the one that makes use of overflow operators) would be not only more succinct, but also much more efficient. The only important things you need to note about this iteration of the same function is that it gives us the expected output, but appears much more drawn out and doesn't use overflow operators.
What I've Noticed: As mentioned, I expected that my newer, cleaner code using overflow operators would perform much more quickly than the iteration that uses a bunch of while loops. When running tests to see how quickly I can generate chess moves, I've found that the version that uses while loops instead of overflow operators was significantly faster. Calculating every combination of the first three moves in a chess game takes the original function a little less than 6 seconds, while the newer function that uses overflow operators takes a little under 13 second.
What I'm Wondering: As I am wanting to create the strongest chess engine possible, I am hunting for bits of my code that I can make execute faster. The old function performing quicker than the new function seems counterintuitive to me. So I am wondering, are overflow operator in Swift notoriously slow/inefficient?
Here is what the class in question that generates these moves looks like: https://github.com/ChopinDavid/Maestro/blob/master/Maestro/Moves.swift
So I am wondering, are overflow operator in Swift notoriously slow/inefficient?
No, if anything the opposite might be true.
The machine-level instructions for multiply etc. may set an overflow flag but they don't do any more than that. For the standard operators Swift has to compile additional instructions to test that flag and generate an error and this code includes branches (though branch prediction should mitigate those effectively).
The code for your overflow operator version is shorter than that for the standard operator version, its also branch-free.
What the performance difference is between versions is another matter, but the overflow version should not be slower.
You probably need to look for your performance difference elsewhere. Happy hunting!
Note: the above comparison is based on fully optimised code ("Fastest, Smallest [-Os]") produced by the Swift compiler in Xcode 11.3.1, a debug build might produce very different results.

Scala - conditionally sum elements in list

I am trying to solve a beginner problem with lists but can't find an example to help me get it work. I am given a list of positive and negative integers (AccountHistory) and I need to check if the negative integers in this list have ever exceeded -1000. I expected my code to work with a freshly introduced helper function like this:
def checkAccount(account: AccountHistory): Boolean = {
def helper(i: AccountHistory): Int = {
var total = 0
i.collect{case x if x < 0 => Math.abs(x) + total}
return total
}
if (helper(account) >1000) true else false
}
But it doesn't work. Please help me find my mistake or problem in wrong approach.
Edit: The pre-given tests include
assert(checkAccount(List(10,-5,20)))
assert(!checkAccount(List(-1000,-1)))
So if assert expects true then my approach is wrong to solve it like this.
By 'exceeded' I mean <-1000, for any or all elements in a list (like exceeding a credit amount in given period).
i.collect{case x if x < 0 => Math.abs(x) + total}
In the above code snippet, not assign back to total, maybe you need:
val total = i.filter(_ < 0).map(Math.abs).sum
I think this is what you're supposed to do:
def checkAccount(account: AccountHistory): Boolean =
account.forall(_ > -1000)

Binary operator "<=" can't be applied to operands of type Bool and Int

if 1 <= A[i] <= 100 || 1 <= B[i] <= 100
for the above line I get these two error.
1. Adjacent operators are in non-associative precedence group 'Comparision Precendence'
2. Binary operator "<=" can not be applied to type BOOL and Int.
try if (1 <= A[i] && A[i] <= 100) || (1 <= B[i] && B[i] <= 100)
Joe's answer and Leo's comment would both work. My preference would be Leo's approach (using 1...100 ~= A[i]), but whatever floats your boat.
That said, let me explain WHY what you did is giving you an error. Without any parenthesis to break it up, it evaluates that going left to right. So if first checks "is 1 <= A[i]?", and that results in a boolean answer. It then tries to ask "is true <= 100?", which makes no sense.

Range Construction Pattern

Given the following code
import std.datetime: Clock, SysTime, Duration;
SysTime[] times;
const n = 3;
foreach (i; 0..n) times ~= Clock.currTime;
is there a simpler, perhaps functional, higher order pattern with
which to achieve the same goal?
A bonus would to be, when possible, minimize copyings of the elements perhaps through some in-place construction pattern.
See also: http://forum.dlang.org/thread/yofbijaejfyftpcjdcvd#forum.dlang.org#post-yofbijaejfyftpcjdcvd:40forum.dlang.org
Update:
Ok here's my try so far:
enum arityMin0(alias fun) = __traits(compiles, fun());
auto apply(alias fun, N)(N n) if (isCallable!fun &&
arityMin0!fun &&
!is(ReturnType!fun == void) &&
isIntegral!N)
{
import std.range: iota, map;
return n.iota.map!(n => fun);
}
called as, for instance,
import std.datetime: Clock;
auto times = 3.apply!(Clock.currTime).array;
One detail left. The restriction
arity!fun == 0
evaluate to false in
auto times = 3.apply!(Clock.currTime).array;
because arity is actually either 0 and 1 here.
So arity!fun evaluates to 1 in this case because Clock.currTime takes a defaulted argument.
Maybe we need arityMin and arityMax in std.traits aswell.
In that case should I use __traits(compiles to implement arityMin?
Evaluating currTime thrice:
auto times = 3.iota.map!(n => Clock.currTime).array();
Evaluating currTime once:
auto times = Clock.currTime.repeat(3).array();