Batching at most 10 at a time over input - loops

I'm trying and failing to accomplish the simple task of batching over input, at most 10 at a time. The follow code almost works:
func batchMe(input []int) {
fmt.Println("Length", len(input), len(input)/10)
for i := 0; i <= len(input)/10; i++ {
from := i * 10
to := (i + 1) * 10
if len(input) < to {
to = len(input)
}
fmt.Println("Batch", i, input[from:to])
}
But you can see from https://play.golang.org/p/_UgFD1iDyse that it prints:
Length 10 1
Batch 0 [1 2 3 4 5 6 7 8 9 10]
Batch 1 []
I don't want it to print Batch 1 in the case of 10 elements!
Perhaps there is a code simplification here?

Elegant solution from Tv on #go-nuts looks like:
for len(input) > 0 {
n := 10
if n > len(input) {
n = len(input)
}
chunk := input[:n]
input = input[n:]
fmt.Println("Batch", chunk)
}
https://play.golang.org/p/Y3U8dUD7Zrr

Related

Finding number(s) that is(are) repeated consecutively most often

Given this array for example:
a = [1 2 2 2 1 3 2 1 4 4 4 5 1]
I want to find a way to check which numbers are repeated consecutively most often. In this example, the output should be [2 4] since both 2 and 4 are repeated three times consecutively.
Another example:
a = [1 1 2 3 1 1 5]
This should return [1 1] because there are separate instances of 1 being repeated twice.
This is my simple code. I know there is a better way to do this:
function val=longrun(a)
b = a(:)';
b = [b, max(b)+1];
val = [];
sum = 1;
max_occ = 0;
for i = 1:max(size(b))
q = b(i);
for j = i:size(b,2)
if (q == b(j))
sum = sum + 1;
else
if (sum > max_occ)
max_occ = sum;
val = [];
val = [val, q];
elseif (max_occ == sum)
val = [val, q];
end
sum = 1;
break;
end
end
end
if (size(a,2) == 1)
val = val'
end
end
Here's a vectorized way:
a = [1 2 2 2 1 3 2 1 4 4 4 5 1]; % input data
t = cumsum([true logical(diff(a))]); % assign a label to each run of equal values
[~, n, z] = mode(t); % maximum run length and corresponding labels
result = a(ismember(t,z{1})); % build result with repeated values
result = result(1:n:end); % remove repetitions
One solution could be:
%Dummy data
a = [1 2 2 2 1 3 2 1 4 4 4 5 5]
%Preallocation
x = ones(1,numel(a));
%Loop
for ii = 2:numel(a)
if a(ii-1) == a(ii)
x(ii) = x(ii-1)+1;
end
end
%Get the result
a(find(x==max(x)))
With a simple for loop.
The goal here is to increase the value of x if the previous value in the vector a is identical.
Or you could also vectorized the process:
x = a(find(a-circshift(a,1,2)==0)); %compare a with a + a shift of 1 and get only the repeated element.
u = unique(x); %get the unique value of x
h = histc(x,u);
res = u(h==max(h)) %get the result

How to generate a sequence of numbers

I want to generate a sequence of numbers in Go but I can't find any built-in functions for this.
Basically I want the equivalent of PHP's range function in Golang:
array range ( mixed $start , mixed $end [, number $step = 1 ] )
It would be useful when creating a slice/array of numeric types and you want to populate/initialize it with a numeric sequence.
There is no equivalent to PHP's range in the Go standard library. You have to create one yourself. The simplest is to use a for loop:
func makeRange(min, max int) []int {
a := make([]int, max-min+1)
for i := range a {
a[i] = min + i
}
return a
}
Using it:
a := makeRange(10, 20)
fmt.Println(a)
Output (try it on the Go Playground):
[10 11 12 13 14 15 16 17 18 19 20]
Also note that if the range is small, you can use a composite literal:
a := []int{1, 2, 3}
fmt.Println(a) // Output is [1 2 3]
1- You may use:
//Create a slice containing a range of elements.
//
// start: First value of the sequence.
// end: The sequence is ended upon reaching the end value.
// step: step will be used as the increment between elements in the sequence.
// step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
if step <= 0 || end < start {
return []int{}
}
s := make([]int, 0, 1+(end-start)/step)
for start <= end {
s = append(s, start)
start += step
}
return s
}
Try it on The Go Playground:
package main
import "fmt"
//Create a slice containing a range of elements.
//
// start: First value of the sequence.
// end: The sequence is ended upon reaching the end value.
// step: step will be used as the increment between elements in the sequence.
// step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
if step <= 0 || end < start {
return []int{}
}
s := make([]int, 0, 1+(end-start)/step)
for start <= end {
s = append(s, start)
start += step
}
return s
}
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]
fmt.Println(NewSlice(10, 19, 1)) // [10 11 12 13 14 15 16 17 18 19]
fmt.Println(NewSlice(10, 28, 2)) // [10 12 14 16 18 20 22 24 26 28]
fmt.Println(NewSlice(-10, -1, 1)) // [-10 -9 -8 -7 -6 -5 -4 -3 -2 -1]
}
2- You may use:
// Returns a slice of elements with exact count.
// step will be used as the increment between elements in the sequence.
// step should be given as a positive, negative or zero number.
func NewSlice(start, count, step int) []int {
s := make([]int, count)
for i := range s {
s[i] = start
start += step
}
return s
}
Try it on The Go Playground:
package main
import "fmt"
func NewSlice(start, count, step int) []int {
s := make([]int, count)
for i := range s {
s[i] = start
start += step
}
return s
}
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]
fmt.Println(NewSlice(10, 10, 1)) // [10 11 12 13 14 15 16 17 18 19]
fmt.Println(NewSlice(10, 10, 2)) // [10 12 14 16 18 20 22 24 26 28]
fmt.Println(NewSlice(-1, 10, -1)) // [-1 -2 -3 -4 -5 -6 -7 -8 -9 -10]
fmt.Println(NewSlice(20, 10, 0)) // [20 20 20 20 20 20 20 20 20 20]
}
package main
import "fmt"
func main() {
var a [11]int
for i := 1; i < len(a); i++ {
a[i] = i
}
fmt.Print(a)
}
You will get:
[0 1 2 3 4 5 6 7 8 9 10]
You can try this code GenerateSequenceInt, it's like Python's range:
package main
import (
"fmt"
"errors"
)
func GenerateSequenceInt(begin, end, step int) (sequence []int){
if step == 0 {
panic(errors.New("step must not be zero"))
}
count := 0
if (end > begin && step > 0) || (end < begin && step < 0) {
count = (end-step-begin)/step + 1
}
sequence = make([]int, count)
for i := 0; i < count; i, begin = i+1, begin+step {
sequence[i] = begin
}
return
}
func main() {
seq1 := GenerateSequenceInt(-1,11,-3)
fmt.Println(seq1)
seq2 := GenerateSequenceInt(1,-1,3)
fmt.Println(seq2)
seq3 := GenerateSequenceInt(1,1,1)
fmt.Println(seq3)
seq4 := GenerateSequenceInt(1, 11, 2)
fmt.Println(seq4)
seq5 := GenerateSequenceInt(1, -11, -2)
fmt.Println(seq5)
}
When you create an array/slice of number in golang, it is automatically populated with 0s. You could use the index instead of the value if you need a 0 based range that increases by 1.
nums := make([]int, 10)
for i := range nums {
//do something with index
fmt.Println(i)
}
If you needed a different starting point (not zero) and step (not 1) of the range, you could calculate it in a loop. For example, for a range of 10 numbers starting at 100, increasing by 5
nums := make([]int, 10)
for i := range nums {
nums[i] = 100 + i*5
}
Wrapping it as a function that returns a slice of numbers
func Range(start int, max int, step int) []int {
count := (max - start) / step
nums := make([]int, count)
for i := range nums {
nums[i] = start + i*step
}
return nums
}
Call it as
nums = Range(-50, 150, 10)
fmt.Println(nums)

Need help with logic (C)

I need to swap first n elements from two non repeating sequences(arrays), where n is a random integer.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
Now i need to repair the sequence by replacing the repeated numbers after '|'.
How to do this?
This is my effort..
for(left1 = 0; left1<pivot; left1++)
{
for(right1 = pivot; right1 < no_jobs; right1++)
{
if(S1->sequence[left1] == S1->sequence[right1])
{
for(left2 = 0; left2<pivot; left2++)
{
for(right2 = pivot; right2<no_jobs; right2++)
{
if(S2->sequence[left2] == S2->sequence[right2])
{
swap_temp = S1->sequence[right1];
S1->sequence[right1] = S2->sequence[right2];
S2->sequence[right2] = swap_temp;
break;
}
}
}
}
}
}
Swapping the first n elements is straightforward using a single for loop.
for(int i = 0; i < n; i++){
int tmp = array1[i];
array1[i] = array2[i];
array2[i] = tmp;
}
Now you need to find what has changed in the arrays. You can do this by comparing the parts you swapped.
int m1 = 0, m2 = 0;
int missing_array1[n];
int missing_array2[n];
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array1[i] == array2[j]){
found = true;
break;
}
}
if(!found){
missing_array2[m2++] = array1[i];
}
}
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array2[i] == array1[j]){
found = true;
break;
}
}
if(!found){
missing_array1[m1++] = array2[i];
}
}
missing_array2 now contains the numbers that are missing from array2. These are all the numbers that will be duplicated in array1. The same goes for missing_array1. Next you need to scan both arrays and replace the duplicates with the missing numbers.
while(m1 >= 0){
int z = 0;
while(missing_array1[m1] != array2[n + z]){
z++;
}
array2[n + z] = missing_array2[m1--];
}
while(m2 >= 0){
int z = 0;
while(missing_array2[m2] != array1[n + z]){
z++;
}
array1[n + z] = missing_array1[m2--];
}
In summary, you compare the parts you swapped to find the values that will be missing from each array. These value are also the values that will be duplicated in the opposite array. Then you scan each of the arrays and replace the duplicate values with one of the missing values (I assume you don't care which of the missing values, as long as all the values are unique.
If the swapped portions of the sequences contain the same values, then there would be no repeats - performing the swap would just shuffle the first n elements. So the values you need to repair are the values which occur in one of the swapped sequences
Firstly, I'd create a histogram of the n swapped elements, with those from sequence 1 counting as bit 0, and those from sequence 2 as bit 1. If any members of the histogram are non-zero, then they occur in one or the other sequence only.
If there are values requiring repair, then you can construct a look-up table of the values which require rewriting. This should map i to i unless i is one of the asymmetric values in the histogram, in which case it needs to map to the another asymmetric value.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
histogram
value 1 2 3 4 5 6 7 8 9
count 3 1 1 2 2 2 0 0 1
mapping for sequence 1 ( while histogram [S1[i]] & 1, replace[S1[i]] with S2[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 6 5 4 5 6 7 8 4
apply mapping to sequence 1 for i > n
Seq1: 3 9 1 2 | 9 8 2 3 7
replace - - - - | 4 8 6 5 7
result 3 9 1 2 | 4 8 6 5 7
mapping for sequence 2 ( while histogram [S2[i]] & 2, replace[S2[i]] with S1[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 2 3 9 3 2 7 8 9
apply mapping to sequence 1 for i > n
Seq2: 1 4 5 6 | 8 7 4 5 6
replace - - - - | 8 7 9 3 2
result 1 4 5 6 | 8 7 9 3 2
Alternatively, replace with the next value with the other bit set in the histogram (the iterated replace will also need to check for replacing a value with itself); I'm assuming it doesn't really matter what value is used as the replacement as long as the values in the result are unique.

Functional way to get a matrix from text

I'm trying to solve some Google Code Jam problems, where an input matrix is typically given in this form:
2 3 #matrix dimensions
1 2 3 4 5 6 7 8 9 # all 3 elements in the first row
2 3 4 5 6 7 8 9 0 # each element is composed of three integers
where each element of the matrix is composed of, say, three integers. So this example should be converted to
#!scala
Array(
Array(A(1,2,3),A(4,5,6),A(7,8,9),
Array(A(2,3,4),A(5,6,7),A(8,9,0),
)
An imperative solution would be of the form
#!python
input = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""
lines = input.split('\n')
class Aclass:
def __init__(self,a,b,c):
pass
print lines[0]
m,n = (int(x) for x in lines[0].split())
array = []
row = []
A = []
for line in lines[1:]:
for elt in line.split():
A.append(elt)
if len(A)== 3:
row.append(Aclass(A[0],A[1],A[2]))
A = []
array.append(row)
row = []
from pprint import pprint
pprint(array)
A functional solution I've thought of is
#!scala
def splitList[A](l:List[A],i:Int):List[List[A]] = {
if (l.isEmpty) return List[List[A]]()
val (head,tail) = l.splitAt(i)
return head :: splitList(tail,i)
}
def readMatrix(src:Iterator[String]):Array[Array[TrafficLight]] = {
val Array(x,y) = src.next.split(" +").map(_.trim.toInt)
val mat = src.take(x).toList.map(_.split(" ").
map(_.trim.toInt)).
map(a => splitList(a.toList,3).
map(b => TrafficLight(b(0),b(1),b(2))
).toArray
).toArray
return mat
}
But I really feel it's the wrong way to go because:
I'm using the functional List structure for each line, and then convert it to an array. The whole code seems much less efficeint
I find it longer less elegant and much less readable than the python solution. It is harder to which of the map functions operates on what, as they all use the same semantics.
What is the right functional way to do that?
val x = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""
val a = x split "\n" map (_.trim.split(" "))
val rows = a(0)(0).toInt
val columns = a(0)(1).toInt
val matrix = (a drop 1) map (_ grouped columns toList) toList
And to print the result:
matrix.map(_.map(_.mkString("(",",",")")).mkString("(",",",")")).mkString("\n")
res1: String =
((1,2,3),(4,5,6),(7,8,9))
((2,3,4),(5,6,7),(8,9,0))
with the assumptions:
assert(rows == matrix.length)
assert(matrix.forall(_.forall(_.size == columns)))
To produce an array tabulate fits better:
val a = x split "\n" map (_.trim.split(" "))
val rows = a(0)(0).toInt
val columns = a(0)(1).toInt
val matrix = Array.tabulate(rows, a(1).size / columns, columns)(
(i,j,k) => a(i + 1)(j * columns + k))
Here's a version that works on Scala 2.7:
val x = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""
val a = x.trim split "\n" map (_.trim.split(" "))
val rows = a(0)(0).toInt
val columns = a(0)(1).toInt
def intervals(n: Int) = (Stream from (0, n)) zip (Stream from (n, n))
val matrix = (a drop 1) map (v =>
intervals(v.size / columns)
take columns
map Function.tupled(v.subArray)
toArray
) toArray
val repr = matrix map (
_ map (
_ mkString ("Array(", ", ", ")")
)
mkString ("Array(", ", ", ")")
) mkString ("Array(\n\t", ",\n\t", "\n)")
println(repr)
I asked a question recently that is very similar. I think you will find the answer there.
find unique matrices from a larger matrix
The input begins as a String, and in the process is transformed into series of 2D matrices.
Lets try this then... seems your not too woried about language, so I'll just describe the code for it.
so we shall have our function that takes in this string, and returns a multi-dimensional array.
The first thing the funciton needs to do is read the string until it gets a space, then convert this sub string into a int and store it as 'rows', then do the same again but store it as 'columns'.
Next, it will need to loop through the remainder of the string, reading out numbers and storing them as ints in an array.
Then it needs to calculate the amount of numbers per cell, which should be "rows * columns / numbers_of_ints" That divide should be the one that would say "16 / 5 = 3" not "16 / 5 = 1" or 16 / 5 = 3.2222...".
Then we create our our array of length rows, where each element is an array of length columsn, where each element is and array of length 'numbers per cell'. This 3D array lets us still access each and every number stored.
now we need to loop through each cell and put its numbers into it.
for(i = 0 ; i < rows ; i = i + 1)
{
for(j = 0 ; j < columns ; j = j + 1)
{
for(k = 0 ; k < numbers_per_cell ; k = k + 1)
{
matrix[i][j][k] = numbers[( i * columns ) + j + k]
}
}
}
You should now have a matrix which contains all of our numbers as a single int stored some where with in the array.
should look like
Array(
Array(Array(1,2,3),Array(4,5,6),Array(7,8,9),
Array(Array(2,3,4),Array(5,6,7),Array(8,9,0),
)
Hope this helps you. I will update it if I need explain something better, or some one has a suggestion.

Formula needed: Sort array to array-"zig-zag"

I have the following array:
a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
I use it for some visual stuff like this:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now I want to sort the array like this to have a "zig-zag" when rendering later.
// rearrange the array according to this schema
1 3 6 10
2 5 9 13
4 8 12 15
7 11 14 16
// the original array should look like this:
a = [1,5,2,9,6,3,13,10,7,4,14,11,8,15,12,16]
// the second index to draw should be the first index in the second row,
// which is represent by 5 in the original 1D Array
Yeah, now I'm looking for a smart formula to do that
ticker = 0;
rows = 4; // can be n
cols = 4; // can be n
originalArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
newArray = [];
while(ticker < originalArray.length)
{
//do the magic here
ticker++;
}
You can leave it sorted in the original order, you just have to step through it differently. EDIT: Turns out that my naive implementation didn't account for the differing step size based on the diagonal. The code below does and has been tested in C#.
var diagonals = new [] { 1, 2, 3, 4, 4, 3, 2, 1 };
for (int i = 0, m = 0; m < 4; i = i + m, ++m) {
for (int j = m, k = 0; k < 4; j = j + diagonals[m+k+1], ++k) {
Console.Write( i+j+1 );
Console.Write( " " );
}
Console.WriteLine();
}
Obviously, you could use this algorithm to fill a new array if you needed to keep that ordering around. It should also scale -- you just need to change the termination conditions to the square root of the array size and automate the generation of the diagonals.
Look at the structure of your matrix:
1 3
| / /
| / /
|/ / ...
2 / 5
/ /
/ /
4
The 1st row starts at 1
The 2nd row starts at 2 = 1 + 1 (# elements in 1st zig)
The 3rd row starts at 4 = 1
+ 1 (# elements in 1st zig)
+ 2 (# elements in 2nd zig)
...
The 3rd row ends at 6 = start of 3rd row + row num
= 4 + 3 = 7
You can derive a closed form formula for the ith row and go ahead.

Resources