I found how to convert hexa string into bytes [UInt8] but I have not found how to convert bytes [UInt8] into an hexa string in Swift
this hexstring convert to string code:
static func bytesConvertToHexstring(byte : [UInt8]) -> String {
var string = ""
for val in byte {
//getBytes(&byte, range: NSMakeRange(i, 1))
string = string + String(format: "%02X", val)
}
return string
}
samething like this result:
"F063C52A6FF7C8904D3F6E379EB85714ECA9C1CB1E8DFD6CA5D3B4A991269D60F607C565C327BD0ECC0985F74E5007E0D276499E1ADB4E0C92D8BDBB46E57705B2D5390FF5CBD4ED1B850C537301CA7E"
UInt8 array: [0, 11, 8, 15, 6, 6, 5, 8, 8, 4, 14, 14, 0, 0, 9, 12, 6, 4, 10, 6, 4, 8, 6, 2, 14, 2, 6, 13, 3, 3, 12, 4, 3, 12, 8, 13, 14, 4, 10, 1, 12, 15, 4, 0, 14, 14, 0, 8, 8, 14, 6, 15, 2, 2, 9, 15, 13, 6, 2, 6, 8, 15, 4, 2, 12, 1, 0, 13, 13, 4, 6, 0, 9, 6, 8, 2, 7, 0, 6, 1, 3, 3, 9, 15, 5, 7, 12, 8, 7, 5, 13, 14, 15, 6, 7, 6, 12, 6, 7, 7, 11, 9, 6, 0, 14, 5, 6, 14, 1, 5, 13, 10, 12, 13, 14, 2, 13, 14, 4, 7, 13, 0, 3, 10, 6, 11, 9, 12, 7, 11, 5, 3, 5, 11, 4, 9, 6, 10, 14, 0, 11, 7, 15, 9, 3, 14, 5, 1, 10, 14, 5, 6, 12, 4, 12, 14, 4, 3, 9, 8, 0]
Xcode 11 • Swift 5.1 or later
extension StringProtocol {
var hexa: [UInt8] {
var startIndex = self.startIndex
return (0..<count/2).compactMap { _ in
let endIndex = index(after: startIndex)
defer { startIndex = index(after: endIndex) }
return UInt8(self[startIndex...endIndex], radix: 16)
}
}
}
extension DataProtocol {
var data: Data { .init(self) }
var hexa: String { map { .init(format: "%02x", $0) }.joined() }
}
"0f00ff".hexa // [15, 0, 255]
"0f00ff".hexa.data // 3 bytes
"0f00ff".hexa.data.hexa // "0f00ff"
"0f00ff".hexa.data as NSData // <0f00ff>
Note: Swift 4 or 5 syntax click here
Thanks to Brian for his routine. It could conveniently be added as a Swift extension as below.
extension Array where Element == UInt8 {
func bytesToHex(spacing: String) -> String {
var hexString: String = ""
var count = self.count
for byte in self
{
hexString.append(String(format:"%02X", byte))
count = count - 1
if count > 0
{
hexString.append(spacing)
}
}
return hexString
}
}
Example of call:
let testData: [UInt8] = [15, 0, 255]
print(testData.bytesToHex(spacing: " ")) // 0F 00 FF
One liner:
testData.map{ String(format:"%02X", $0) }.joined(separator: " ")
XCode 12-beta 6.
I know its late but I use this simple routine that gives an arbitrary spacing. I converted it from Java on Android. I also have C and other language versions of this - it easy to go from language to language when you cant remember all the language-specific libraries.
public static func bytesToHex(bytes: [UInt8], spacing: String) -> String
{
var hexString: String = ""
var count = bytes.count
for byte in bytes
{
hexString.append(String(format:"%02X", byte))
count = count - 1
if count > 0
{
hexString.append(spacing)
}
}
return hexString
}
It creates a two-digit hex string with an arbitrary spacing string between elements. I use it like this, for example, to display the results of a characteristic read
let charValue = [UInt8](characteristic.value ?? Data())
print("Characteristic \(characteristic.uuid) read with value: \(Btle.bytesToHex(bytes: charValue, spacing: " "))")
with an output that looks like this:
Characteristic System ID read with value: 00 1C 05 FF FE FF E8 74
My experience with Swift and iOS is very limited; perhaps the seasoned Swift people can 'Swiftify' it.
Related
I want to know in Flutter if my sequence exists in the other sequenceTwo. For the example, I made two identical List<List<int>> that work. But I also want to know if it exists even if there are more record before or after the sequence as in the next check I do in the code below.
List<List<int>> sequence = [];
sequence.add(Uint8List.fromList([42, 6, 1, 8, 6, 63, 13, 10]));
sequence.add(Uint8List.fromList([42, 6, 1, 8, 9, 66, 13, 10]));
sequence.add(Uint8List.fromList([42, 6, 1, 8, 0, 57, 13, 10]));
sequence.add(Uint8List.fromList([42, 6, 1, 8, 3, 60, 13, 10]));
List<List<int>> sequenceTwo = [];
sequenceTwo.add(Uint8List.fromList([42, 6, 1, 8, 6, 63, 13, 10]));
sequenceTwo.add(Uint8List.fromList([42, 6, 1, 8, 9, 66, 13, 10]));
sequenceTwo.add(Uint8List.fromList([42, 6, 1, 8, 0, 57, 13, 10]));
sequenceTwo.add(Uint8List.fromList([42, 6, 1, 8, 3, 60, 13, 10]));
Function deepEqOne = const DeepCollectionEquality().equals;
debugPrint(
'DeepCollection: ' + deepEqOne(sequence, sequenceTwo).toString()); // true so works!
sequenceTwo.add(Uint8List.fromList([42, 6, 1, 9, 3, 60, 13, 10]));
debugPrint(
'DeepCollection: ' + deepEqOne(sequence, sequenceTwo).toString()); // false but I want this also to work somehow
I have an array like this, and I need to multiply a number if it is 3, but in the end reduce eliminates all numbers equal to 3, and multiplies the rest. How do I fix this ?
let arr = [2, 4, 3, 1, 4, 3, 1, 3, 10, 4, 2, 13]
let aaa = arr.reduce([]) { $1 == 3 ? $0 : $0 + [$1 * 5] }
//[10, 20, 5, 20, 5, 50, 20, 10, 65]
//[2,4,15,1,4,15,1,15,10,4,2,13] need this
You should use map instead of reduce
let arr = [2, 4, 3, 1, 4, 3, 1, 3, 10, 4, 2, 13]
let result = arr.map { $0 == 3 ? 15 : $0 }
// [2, 4, 15, 1, 4, 15, 1, 15, 10, 4, 2, 13
Or if it should work for any multiple of 3
let result = arr.map { $0.isMultiple(of: 3) ? $0 * 5 : $0 }
How can I print type of largest number in this dictionary?
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var typeoflargest:String = " "
for (kind, numbers) in interestingNumbers {
for type in kind.characters {
for number in numbers {
if number > largest {
largest = number
typeoflargest = String(type)
}
}
}
}
print(largest)
print(typeoflargest)
output:
25
S
why I got only first character "S" instead of "Square"?
There is no reason to be iterating the characters of the kind string. Just do the following:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var typeoflargest:String = ""
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
typeoflargest = kind
}
}
}
print(largest)
print(typeoflargest)
Output:
25
Square
Alternative approach:
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
let maximum = interestingNumbers
.map{ type, numbers in return (type: type, number: numbers.max()!) }
.max(by: { $0.number < $1.number })!
print(maximum.type, maximum.number)
Explanation:
First, get the maximal element of each category. Do this by iterating the dictionary, mapping the values from arrays of numbers to maximum numbers (within their respective arrays), yielding:
[
(type: "Square", number: 25), // 25 is the max of [1, 4, 9, 16, 25]
(type: "Prime", number: 13), // 13 is the max of [2, 3, 5, 7, 11, 13]
(type: "Fibonacci", number: 8) // 8 is the max of [1, 1, 2, 3, 5, 8]
]
Then, get the maximal type/number pair, by comparing their numbers, yielding the result:
(type: "Square", number: 25) // 25 is the max of 25, 13, 8
I am working on N-Queens problem and to check whether the queen has been already placed on upper and lower left diagonals, I am finding difficulty in formulating for loop condition.
func isPlaceable(row: Int, column: Int) -> Bool {
// check if one same row another queen exits
for i in 0..<column {
if (solution[row][i] == 1) {
return false
}
}
// check upper left diagonal
// in C or C++ I can do
// for (int i = row, int j = col; i >= 0 && j >= 0; i--, j--) {
// if (board[i][j])
// return false;
//}
}
What would be Swifty way of doing it i.e. Combing the two condition?
One possible solution is you can use zip(_:_:) with two sequence.
func isPlaceable(row: Int, column: Int) -> Bool {
// check if one same row another queen exits
for i in 0..<column {
if (solution[row][i] == 1) {
return false
}
}
// check upper left diagonal
let seq1 = (0...row).reversed()
let seq2 = (0...column).reversed()
for (i,j) in zip(seq1, seq2) {
if (board[i][j]) {
return false
}
}
//your code
}
var i = row
var j = col
while (i >= 0 && j >= 0) {
if (board[i][j])
return false;
i -= 1
j -= 1
}
This type of process benefits a lot from double indirection and prepared matrices.
For example, you could give an identifier to each line segment on the board and check that no two queens use the same line segment.
There are 46 line segments on a standard chess board:
8 vertical
8 horizontal
30 diagonals (15 each)
(I numbered them 1 through 46)
When the queens are properly placed, they will each use 4 line segments (axes) that no other queen uses. Sets are the ideal structure to check for this non intersecting union. By preparing a matrix with a Set of 4 axis identifiers at each row/column, a simple union of the sets for the 8 queens will tell us if they align with each other.
// vertical axes (1...8)
let vAxis = [ [ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ],
[ 1, 2, 3, 4, 5, 6, 7, 8 ]
]
// horizontal axes (9...16)
let hAxis = [ [ 9, 9, 9, 9, 9, 9, 9, 9 ],
[ 10, 10, 10, 10, 10, 10, 10, 10 ],
[ 11, 11, 11, 11, 11, 11, 11, 11 ],
[ 12, 12, 12, 12, 12, 12, 12, 12 ],
[ 13, 13, 13, 13, 13, 13, 13, 13 ],
[ 14, 14, 14, 14, 14, 14, 14, 14 ],
[ 15, 15, 15, 15, 15, 15, 15, 15 ],
[ 16, 16, 16, 16, 16, 16, 16, 16 ],
]
// up right axes (17...31)
let uAxis = [ [ 17, 18, 19, 20, 21, 22, 23, 24 ],
[ 18, 19, 20, 21, 22, 23, 24, 25 ],
[ 19, 20, 21, 22, 23, 24, 25, 26 ],
[ 20, 21, 22, 23, 24, 25, 26, 27 ],
[ 21, 22, 23, 24, 25, 26, 27, 28 ],
[ 22, 23, 24, 25, 26, 27, 28, 29 ],
[ 23, 24, 25, 26, 27, 28, 29, 30 ],
[ 24, 25, 26, 27, 28, 29, 30, 31 ],
]
// down right axes (32...46)
let dAxis = [ [ 39, 40, 41, 42, 43, 44, 45, 46 ],
[ 38, 39, 40, 41, 42, 43, 44, 45 ],
[ 37, 38, 39, 40, 41, 42, 43, 44 ],
[ 36, 37, 38, 39, 40, 41, 42, 43 ],
[ 35, 36, 37, 38, 39, 40, 41, 42 ],
[ 34, 35, 36, 37, 38, 39, 40, 41 ],
[ 33, 34, 35, 36, 37, 38, 39, 40 ],
[ 32, 33, 34, 35, 36, 37, 38, 39 ],
]
// Set of axis numbers for each [row][col] of the board
let axes = (0..<8).map()
{
row in (0..<8).map()
{ Set([ vAxis[row][$0], hAxis[row][$0], uAxis[row][$0], dAxis[row][$0] ]) }
}
// position of each queen ( column number at each row )
var queenCols = [5, 3, 6, 0, 7, 1, 4, 2]
// Check if each queen in queenCols is on its own 4 axes
// We will have 32 (8 x 4) different axes used if no queen aligns with another
let fullCover = queenCols.enumerated()
.reduce(Set<Int>()){ $0.union(axes[$1.0][$1.1]) }
.count == 32
This "fullCover" check can be used in a brute force loop on all 16,777,216 combinations or it can be refined to perform incremental checks in an optimized search tree. (BTW the brute force solution takes only 80 seconds to compute on a MacBook Pro)
So, in the end, you can avoid for loops altogether.
[EDIT] function to find the 92 solutions in a brute force loop:
public func queenPositions() -> [[Int]]
{
var result : [[Int]] = []
let rows : [Int] = Array(0..<8)
for i in 0..<16777216
{
var N:Int = i
let queenCols = rows.map{ _ -> Int in let col = N % 8; N = N / 8; return col}
let fullCover = queenCols.enumerated()
.reduce(Set<Int>()){ $0.union(axes[$1.0][$1.1]) }
.count == 32
if fullCover { result.append(queenCols) }
}
return result
}
[EDIT2] Using the set matrices in an optimized tree search produces the 92 solutions in 0.03 second.
Here is the optimized (and generic) function:
public func queenPositions2(boardSize:Int = 8) -> [[Int]]
{
let vAxis = (0..<boardSize).map{ _ in (0..<boardSize).map{$0} }
let hAxis = (0..<boardSize).map{ Array(repeating:$0+boardSize, count:boardSize) }
let uAxis = (0..<boardSize).map{ row in (0..<boardSize).map{ 2 * boardSize + row + $0} }
let dAxis = (0..<boardSize).map{ row in (0..<boardSize).map{ 5 * boardSize - row + $0} }
let axes = (0..<boardSize).map()
{
row in (0..<boardSize).map()
{ Set([ vAxis[row][$0], hAxis[row][$0], uAxis[row][$0], dAxis[row][$0] ]) }
}
var result : [[Int]] = []
var queenCols : [Int] = Array(repeating:0, count:boardSize)
var colAxes = Array(repeating:Set<Int>(), count:boardSize)
var queenAxes = Set<Int>()
var row = 0
while row >= 0
{
if queenCols[row] < boardSize
{
let newAxes = axes[row][queenCols[row]]
if newAxes.isDisjoint(with: queenAxes)
{
if row == boardSize - 1
{
result.append(queenCols)
queenCols[row] = boardSize
continue
}
else
{
colAxes[row] = newAxes
queenAxes.formUnion(newAxes)
row += 1
queenCols[row] = 0
continue
}
}
}
else
{
row -= 1
if row < 0 { break }
}
queenAxes.subtract(colAxes[row])
colAxes[row] = Set<Int>()
queenCols[row] += 1
}
return result
}
Given a 10x10 board, the 724 solutions are generated in 0.11 second.
[EDIT3] one liner "for loop" ...
You can generate an array of (row,column) coordinate for the 4 axes of a given position and use that as your data in the for loop:
func isPlaceable(row: Int, column: Int) -> Bool
{
var coverage = (0..<8).map{($0,column)} // horizontal
coverage += (0..<8).map{(row,$0)} // vertical
coverage += zip((max(0,row-column)..<8),(max(0,column-row)..<8)) // diagonal down
coverage += zip((0...min(7,row+column)).reversed(),(max(0,column+row-7)..<8)) // diagonal up
// return !coverage.contains{solution[$0][$1] == 1}
for (r,c) in coverage
{
if solution[r][c] == 1 { return false }
}
return true
}
It feels wasteful to rebuild the whole coverage list every time though. I would compute it once for every coordinate and place it in a row/column matrix for reuse in the isPlaceable() function.
I have an external list in a txt file, I need to grab the first string and use it as a key, thats fine it works, and then I need a list of the numbers afterwards. However I only get the first, what have I done wrong?
So current output would be SK1, 9 - SK2, 0 etc when I need this to be the full list not just the first number.
I am using Scala on Intelije
/**
* Created by Andre on 10/11/2016.
*/
import scala.io.Source
import scala.io.StdIn.readInt
import scala.io.StdIn.readLine
import scala.collection.immutable.ListMap
object StockMarket extends App{
// APPLICATION LOGIC
// reads the data from text file
val mapdata = readFile("data.txt")
// print data to check it's been read in correctly
println(mapdata)
// *******************************************************************************************************************
// UTILITY FUNCTIONS
// reads data file - comma separated file
def readFile(filename: String): Map[String, Int] = {
// create buffer to build up map as we read each line
var mapBuffer: Map[String, Int] = Map()
try {
for (line <- Source.fromFile(filename).getLines()) { // for each line
val splitline = line.split(",").map(_.trim).toList // split line at , and convert to List
// add element to map buffer
// splitline is line from file as List, e.g. List(Bayern Munich, 24)
// use head as key
// tail is a list, but need just the first (only in this case) element, so use head of tail and convert to int
mapBuffer = mapBuffer ++ Map(splitline.head -> splitline.tail.head.toInt)
}
} catch {
case ex: Exception => println("Sorry, an exception happened.")
}
mapBuffer
}
}
My external List
SK1, 9, 7, 2, 0, 7, 3, 7, 9, 1, 2, 8, 1, 9, 6, 5, 3, 2, 2, 7, 2, 8, 5, 4, 5, 1, 6, 5, 2, 4, 1
SK2, 0, 7, 6, 3, 3, 3, 1, 6, 9, 2, 9, 7, 8, 7, 3, 6, 3, 5, 5, 2, 9, 7, 3, 4, 6, 3, 4, 3, 4, 1
SK4, 2, 9, 5, 7, 0, 8, 6, 6, 7, 9, 0, 1, 3, 1, 6, 0, 0, 1, 3, 8, 5, 4, 0, 9, 7, 1, 4, 5, 2, 8
SK5, 2, 6, 8, 0, 3, 5, 5, 2, 5, 9, 4, 5, 3, 5, 7, 8, 8, 2, 5, 9, 3, 8, 6, 7, 8, 7, 4, 1, 2, 3
SK6, 2, 7, 5, 9, 1, 9, 8, 4, 1, 7, 3, 7, 0, 8, 4, 5, 9, 2, 4, 4, 8, 7, 9, 2, 2, 7, 9, 1, 6, 9
SK7, 6, 9, 5, 0, 0, 0, 0, 5, 8, 3, 8, 7, 1, 9, 6, 1, 5, 3, 4, 7, 9, 5, 5, 9, 1, 4, 4, 0, 2, 0
SK8, 2, 8, 8, 3, 1, 1, 0, 8, 5, 9, 0, 3, 1, 6, 8, 7, 9, 6, 7, 7, 0, 9, 5, 2, 5, 0, 2, 1, 8, 6
SK9, 7, 1, 8, 8, 4, 4, 2, 2, 7, 4, 0, 6, 9, 5, 5, 4, 9, 1, 8, 6, 3, 4, 8, 2, 7, 9, 7, 2, 6, 6
Here is your code with minimal changes:
// I split it on two functions just to facilitate testing:
def readFile(filename: String): Map[String, List[Int]] = {
processInput(Source.fromFile(filename).getLines)
}
def processInput(lines: Iterator[String]): Map[String, List[Int]] = {
var mapBuffer: Map[String, List[Int]] = Map()
try {
for (line <- lines) {
val splitline = line.split(",").map(_.trim).toList
// here instead of taking .tail.head, we map over the tail (all numbers):
mapBuffer = mapBuffer + (splitline.head -> splitline.tail.map(_.toInt))
}
} catch {
case ex: Exception => println("Sorry, an exception happened.")
}
mapBuffer
}
And here is a solution, which I believe, is more a idiomatic Scala code:
import scala.util.Try
def processInput(lines: Iterator[String]): Map[String, List[Int]] = {
Try {
lines.foldLeft( Map[String, List[Int]]() ) { (acc, line) =>
val splitline = line.split(",").map(_.trim).toList
acc.updated(splitline.head, splitline.tail.map(_.toInt))
}
}.getOrElse {
println("Sorry, an exception happened.")
Map()
}
}
The differences mainly are
not using var
not using mutable Map (by the way, you don't need a var to mutate
it)
using foldLeft to iterate and accumulate the Map instead of for
using
scala.util.Try
instead of try-catch.