What's Swift's "fromAfter" call in array slices? - swift3

Swift 3 has upTo and through
which are noninclusive, inclusive respectively
func prefix(upTo: Int)
Returns a subsequence from the start of the collection up to, but not including, the specified position.
.
func prefix(through: Int)
Returns a subsequence from the start of the collection through the specified position.
for the other end it has from
func suffix(from: Int)
Returns a subsequence from the specified position to the end of the collection.
which seems to be inclusive
What's the non-inclusive call at the far end??
// sum the numbers before, and after, an index i...
let lo = A.prefix(upTo: i).reduce(0,+) // means noninclusive
let hi = A.suffix(from: i+1).reduce(0,+) // 'from' seems to mean inclusive
what's the call I don't know? It sucks to have to write from with +1.

There is currently no non-inclusive suffix method for for Collection types in the stdlib, but for this use case, you can readily implement your own by combining suffix(from:) with dropFirst(_:) (which, imho, better shows intent than from: idx+1), e.g.
extension Collection where SubSequence == SubSequence.SubSequence {
public func suffix(after start: Index) -> SubSequence {
return suffix(from: start).dropFirst(1)
}
}
Applied to your example (separately sum numbers before and after a given partitioning number (or, index of), not including the partitioning one):
/* in this example, invalid indices will yield a full-array sum into
lo or hi, depending on high or low index out of bounds, respectively */
func splitSum(of arr: [Int], at: Int) -> (Int, Int) {
guard at < arr.count else { return (arr.reduce(0, +), 0) }
guard at >= 0 else { return (0, arr.reduce(0, +)) }
let lo = arr.prefix(upTo: at).reduce(0, +)
let hi = arr.suffix(after: at).reduce(0, +)
return (lo, hi)
}
// example usage
let arr = [Int](repeating: 1, count: 10)
print(splitSum(of: arr, at: 4)) // (4, 5)
Leaving the subject of a non-inclusive suffix method, an alternative approach to your split sum calculation would be to use one of the split(...) methods for Collection types:
func splitSum(of arr: [Int], at: Int) -> (Int, Int) {
guard at < arr.count else { return (arr.reduce(0, +), 0) }
guard at >= 0 else { return (0, arr.reduce(0, +)) }
let sums = arr.enumerated()
.split (omittingEmptySubsequences: false) { $0.0 == at }
.map { $0.reduce(0) { $0 + $1.1 } }
guard let lo = sums.first, let hi = sums.last else { fatalError() }
return (lo, hi)
}
// example: same as above
I believe the split version is a bit more verbose, however, and also semantically poorer at showing the intent of the code.

Related

Dart - General Summation Function For 'double', 'int', and 'num' Number Types

mySumFunction(myIntList) =
mySumFunction(myDoubleList) =
mySumFunction(myNumList) =
Can a single function calculate all these above? Most functions that can accept num or List<num> as an input can also accept double & int and List<double> & List<int> as inputs as well respectively. Functions involving .reduce() though appear to be some of the exceptions.
sumList(List<num> temp) {
return (temp.reduce((value, element) => (value + element)));
} //Only works with num type variables
Code fixed for Dart 2.13:
// #dart=2.13
T sumList<T extends num>(List<T> temp) {
var result = temp.reduce((value, element) => (value + element) as T);
return result;
}
void main() {
print(sumList<double>([2,3,4.5,5,6]));
}
Result:
20.5
Unless you are specifically looking for a solution using reduce, a forEach can be used compute the sum of nums ints or doubles in a function.
sum(List<num> list) {
var total = 0;
for (var x in list) {
total += x;
}
return total;
}
A shorthand for this is the fold function which is pretty much reduce with an initial value, and it solves the type issue. The following function works on nums doubles or ints.
sumByFolding(List<num> list) {
return list.fold(0, (prev, element) => prev + element);
}
Unlike the reduce function, fold is also safe to use for empty collections.
Another alternative:
sumList(List<num> temp) {
return([...temp].reduce((value, element) => value + element));
}

timing comparison between max() and ?: operator

I write a function to return the max depth of binary tree.
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == 0) return 0;
if((root -> left ==0) &&(root->right == 0)) return 1;
**************
}
};
I wrote two methods for the ***** part
Method1:
else return max((1+maxDepth(root -> left)),(1+maxDepth(root -> right)));
Method2 :
else return (maxDepth(root -> left) > maxDepth(root -> right)) ?
(maxDepth(root->left) + 1):
(maxDepth(root->right) + 1);
The second method failed timing check while the first one passes.
They look pretty similar to me.
Anyone can give some hints why the second method is slower?
The first approach is similar to:
else {
auto l = 1 + maxDepth(root -> left);
auto r = 1 + maxDepth(root -> left);
return (l > r) ? l : r;
}
Note that maxDepth() is only invoked twice.
In your second approach, maxDepth() is invoked twice in the conditional expression, and is then invoked a third time in either the true-expression or false-expression (depending on the outcome of the conditional). This wastes time recomputing the value.
Depending on the state of the tree, this approach could take anywhere between the same amount of time as the first approach, and twice the amount of time as the first approach.

Swift 3 and code converter for looping arrays reversely

I have this code which is not compatible with swift3
for var i = FCatalogIdx-1; i > -1; i -=1 {
// access items in array FCaalogArr
}
Code converter suggest converting to
for i in ((-1 + 1)...FCatalogIdx-1).reversed() {
which seems to be the the same as:
for i in (0...FCatalogIdx-1).reversed() {
Is this the closest I can get to my old code? And if so, is it recommended to use the code converter suggestion - the (-1 + 1) looks ugly, but I suspect it is to give a hint of the original c-style loop logic?
You shouldn't use the (-1+1) because that is just needlessly confusing. Also, use the half-open range operator ..< to create a range that doesn't include the final index:
for i in (0 ..< FCatalogIdx).reversed() {
}
The advantage of the half-open range operator ..< over the closed range operator ... is that it is possible to create an empty range.
Consider this example:
let n = 0
for i in 0 ..< n {
print("hello") // range is empty, so this is never printed
}
for i in 0 ... n-1 { // fatal error: Can't form Range with upperBound < lowerBound
print("hello")
}
for i in FCaalogArr.indicies.reversed() would be better assuming FCaalogIdx is the last index of the array

What is the nil or "empty" countable range in Swift?

In Swift3,
let highestIndex = 7
for index in 1 ..< highestIndex {
latter(index)
}
however,
let highestIndex = 0, or anything smaller
for index in 1 ..< highestIndex {
latter(index)
}
that crashes.
So, the ..< operator is impractical in most situations.
So, perhaps, something like this ...
for index in (1 ..< highestIndex).safely() {
latter(index)
}
How would one write the extension safely ?
Or at worst just a function safely(from,to) which returns a CountableRange, or, an "empty" (?) countable range? (I don't understand if a Swift extension can "catch" an error?)
Sticking as closely to the ..< operator as possible the following would be an appropriate implementation of safely.
public func safely<Bound>(_ minimum: Bound, _ maximum: Bound) -> CountableRange<Bound> where Bound : _Strideable & Comparable, Bound.Stride : Integer {
if maximum < minimum {
return CountableRange(uncheckedBounds: (lower: minimum, upper: minimum))
}
return CountableRange(uncheckedBounds: (lower: minimum, upper: maximum))
}
let one = safely(0, 12) // CountableRange(0..<12)
let two = safely(15, 12) // CountableRange(15..<15)
one.isEmpty // false
two.isEmpty // true
You might want to consider giving the parameters better names to indicate wether or not they are inclusive / exclusive bounds, etc.
Creating an extension and adding a .safely() will not work since the bounds are checked when creating the CountableRange before the call to safely could even be done.
I am a fan of simple solutions:
let lowerIndex = 1
let higherIndex = 0
for index in lowerIndex ..< max(lowerIndex, higherIndex) {
latter(index)
}
I'm able to get this to work fine:
for index in 1 ..< 1 {
latter(index)
}
For the <1 case, I recommend something like this:
guard highestIndex > 0 else { return }
for index in 1 ..< highestIndex {
latter(index)
}

How to store output of very large Fibonacci number?

I am making a program for nth Fibonacci number. I made the following program using recursion and memoization.
The main problem is that the value of n can go up to 10000 which means that the Fibonacci number of 10000 would be more than 2000 digit long.
With a little bit of googling, I found that i could use arrays and store every digit of the solution in an element of the array but I am still not able to figure out how to implement this approach with my program.
#include<iostream>
using namespace std;
long long int memo[101000];
long long int n;
long long int fib(long long int n)
{
if(n==1 || n==2)
return 1;
if(memo[n]!=0)
return memo[n];
return memo[n] = fib(n-1) + fib(n-2);
}
int main()
{
cin>>n;
long long int ans = fib(n);
cout<<ans;
}
How do I implement that approach or if there is another method that can be used to achieve such large values?
One thing that I think should be pointed out is there's other ways to implement fib that are much easier for something like C++ to compute
consider the following pseudo code
function fib (n) {
let a = 0, b = 1, _;
while (n > 0) {
_ = a;
a = b;
b = b + _;
n = n - 1;
}
return a;
}
This doesn't require memoisation and you don't have to be concerned about blowing up your stack with too many recursive calls. Recursion is a really powerful looping construct but it's one of those fubu things that's best left to langs like Lisp, Scheme, Kotlin, Lua (and a few others) that support it so elegantly.
That's not to say tail call elimination is impossible in C++, but unless you're doing something to optimise/compile for it explicitly, I'm doubtful that whatever compiler you're using would support it by default.
As for computing the exceptionally large numbers, you'll have to either get creative doing adding The Hard Way or rely upon an arbitrary precision arithmetic library like GMP. I'm sure there's other libs for this too.
Adding The Hard Way™
Remember how you used to add big numbers when you were a little tater tot, fresh off the aluminum foil?
5-year-old math
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
Well you gotta add each column, right to left. And when a column overflows into the double digits, remember to carry that 1 over to the next column.
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
The 10,000th fibonacci number is thousands of digits long, so there's no way that's going to fit in any integer C++ provides out of the box. So without relying upon a library, you could use a string or an array of single-digit numbers. To output the final number, you'll have to convert it to a string tho.
(woflram alpha: fibonacci 10000)
Doing it this way, you'll perform a couple million single-digit additions; it might take a while, but it should be a breeze for any modern computer to handle. Time to get to work !
Here's an example in of a Bignum module in JavaScript
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We can verify that the Wolfram Alpha answer above is correct
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
bigfib (10000)
// "336447 ... 366875"
Expand the program below to run it in your browser
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
console.log (bigfib (10000))
Try not to use recursion for a simple problem like fibonacci. And if you'll only use it once, don't use an array to store all results. An array of 2 elements containing the 2 previous fibonacci numbers will be enough. In each step, you then only have to sum up those 2 numbers. How can you save 2 consecutive fibonacci numbers? Well, you know that when you have 2 consecutive integers one is even and one is odd. So you can use that property to know where to get/place a fibonacci number: for fib(i), if i is even (i%2 is 0) place it in the first element of the array (index 0), else (i%2 is then 1) place it in the second element(index 1). Why can you just place it there? Well when you're calculating fib(i), the value that is on the place fib(i) should go is fib(i-2) (because (i-2)%2 is the same as i%2). But you won't need fib(i-2) any more: fib(i+1) only needs fib(i-1)(that's still in the array) and fib(i)(that just got inserted in the array).
So you could replace the recursion calls with a for loop like this:
int fibonacci(int n){
if( n <= 0){
return 0;
}
int previous[] = {0, 1}; // start with fib(0) and fib(1)
for(int i = 2; i <= n; ++i){
// modulo can be implemented with bit operations(much faster): i % 2 = i & 1
previous[i&1] += previous[(i-1)&1]; //shorter way to say: previous[i&1] = previous[i&1] + previous[(i-1)&1]
}
//Result is in previous[n&1]
return previous[n&1];
}
Recursion is actually discommanded while programming because of the time(function calls) and ressources(stack) it consumes. So each time you use recursion, try to replace it with a loop and a stack with simple pop/push operations if needed to save the "current position" (in c++ one can use a vector). In the case of the fibonacci, the stack isn't even needed but if you are iterating over a tree datastructure for example you'll need a stack (depends on the implementation though). As I was looking for my solution, I saw #naomik provided a solution with the while loop. That one is fine too, but I prefer the array with the modulo operation (a bit shorter).
Now concerning the problem of the size long long int has, it can be solved by using external libraries that implement operations for big numbers (like the GMP library or Boost.multiprecision). But you could also create your own version of a BigInteger-like class from Java and implement the basic operations like the one I have. I've only implemented the addition in my example (try to implement the others they are quite similar).
The main idea is simple, a BigInt represents a big decimal number by cutting its little endian representation into pieces (I'll explain why little endian at the end). The length of those pieces depends on the base you choose. If you want to work with decimal representations, it will only work if your base is a power of 10: if you choose 10 as base each piece will represent one digit, if you choose 100 (= 10^2) as base each piece will represent two consecutive digits starting from the end(see little endian), if you choose 1000 as base (10^3) each piece will represent three consecutive digits, ... and so on. Let's say that you have base 100, 12765 will then be [65, 27, 1], 1789 will be [89, 17], 505 will be [5, 5] (= [05,5]), ... with base 1000: 12765 would be [765, 12], 1789 would be [789, 1], 505 would be [505]. It's not the most efficient, but it is the most intuitive (I think ...)
The addition is then a bit like the addition on paper we learned at school:
begin with the lowest piece of the BigInt
add it with the corresponding piece of the other one
the lowest piece of that sum(= the sum modulus the base) becomes the corresponding piece of the final result
the "bigger" pieces of that sum will be added ("carried") to the sum of the following pieces
go to step 2 with next piece
if no piece left, add the carry and the remaining bigger pieces of the other BigInt (if it has pieces left)
For example:
9542 + 1097855 = [42, 95] + [55, 78, 09, 1]
lowest piece = 42 and 55 --> 42 + 55 = 97 = [97]
---> lowest piece of result = 97 (no carry, carry = 0)
2nd piece = 95 and 78 --> (95+78) + 0 = 173 = [73, 1]
---> 2nd piece of final result = 73
---> remaining: [1] = 1 = carry (will be added to sum of following pieces)
no piece left in first `BigInt`!
--> add carry ( [1] ) and remaining pieces from second `BigInt`( [9, 1] ) to final result
--> first additional piece: 9 + 1 = 10 = [10] (no carry)
--> second additional piece: 1 + 0 = 1 = [1] (no carry)
==> 9542 + 1 097 855 = [42, 95] + [55, 78, 09, 1] = [97, 73, 10, 1] = 1 107 397
Here is a demo where I used the class above to calculate the fibonacci of 10000 (result is too big to copy here)
Good luck!
PS: Why little endian? For the ease of the implementation: it allows to use push_back when adding digits and iteration while implementing the operations will start from the first piece instead of the last piece in the array.