Script
import { forkJoin, zip, combineLatest, Subject, ReplaySubject } from 'rxjs';
import { withLatestFrom, take, first } from 'rxjs/operators';
const letters: string = 'abcdefghijklmnopqrstuvwxyz';
function getLetter(i: number) : string {
const l: string = letters[i].toString();
console.log(` letter ${l}`);
return letters[i].toString();
}
function getNumber(i: number) : string {
const l: string = letters[i].toString();
console.log(` number ${i}`);
return i.toString();
}
const sa = new ReplaySubject<string>(1);
const sz = new ReplaySubject<string>(1);
combineLatest(sa, sz)
.subscribe(([a, z]) => {console.log(`s: ${a}-${z}`);});
var i: number = 0;
var b: boolean = true;
while(i < 10) {
console.log(`i: ${i}`);
sa.next(getNumber(i));
if(b) {
sa.next(getLetter(i));
}
i++;
b = !b;
}
Output
C:\Work\ts-experiments>tsc
C:\Work\ts-experiments>node dist\index.js
i: 0
number 0
letter a
i: 1
number 1
i: 2
number 2
letter c
i: 3
number 3
i: 4
number 4
letter e
i: 5
number 5
i: 6
number 6
letter g
i: 7
number 7
i: 8
number 8
letter i
i: 9
number 9
C:\Work\ts-experiments>
Why nothing from the .subscribe?
(Unfortunately this doesn't work in JSFiddle.)
Because sz never fires. For combineLatest to fire, all of the observables should emit at least once.
Related
I've recently started on HackerRank and I'm attempting "Sales by Match". I've arrived at a solution I'm content with in terms of exploiting Kotlin's function programming capabilities. However, I'm not getting the expected answer...
Problem summary:
Given an Array:
-> find and return the total number of pairs.
i.e:
input -> [10, 20, 20, 10, 10, 30, 50, 10, 20]
number of pairs -> 3
here is my code and some comments to explain it:
fun sockMerchant(n: Int, pile: Array<Int>): Int{
var count = 0
mutableMapOf<Int, Int>().withDefault { 0 }.apply {
// the [attempted] logic behind this piece of code here is
// that as we iterate through the list, the 'getOrPut()'
// function will return either the value for the given [key]
// or throw an exception if there is no such key
// in the map. However, since our map was created by
// [withDefault], the function resorts to its `defaultValue` <-> 0
// instead of throwing an exception.
for (e in values) {
// this simplifies our code and inserts a zero [+1] where needed.
// if (key exists)
// // return its associated value and MOD it:
// case: even -> increment counter
// else -> do nothing
// else if (key dne)
// // insert default value <-> [0] + 1
// ....
// ....
// ....
if (getOrPut(e, { getValue(e) + 1 } ) % 2 == 0) count++
}
}
return count
}
fun main(args: Array<String>) {
val scan = Scanner(System.`in`)
val n = scan.nextLine().trim().toInt()
val ar = scan.nextLine().split(" ").map{ it.trim().toInt() }.toTypedArray()
val result = sockMerchant(n, ar)
println(result)
}
--
Any help or tips would go a long way here:)
I was able to do this by grouping the numbers together, taking the resulting lists, and summing how many pairs each one contains:
fun sockMerchant(n: Int, pile: Array<Int>): Int =
pile.groupBy { it }.values.sumBy { it.size / 2 }
After we do pile.groupBy { it }, we have this structure:
{10=[10, 10, 10, 10], 20=[20, 20, 20], 30=[30], 50=[50]}
We take the values, and sum by each of their size dividing by 2. This will round half-pairs down to 0 and full pairs to 1 each.
Note: I am not entirely clear what the purpose of n is in this case.
I modified it a bit to be more easily testable, but here is the fixes :
import java.util.*
fun sockMerchant(n: Int, pile: Array<Int>): Int{
var count = 0
mutableMapOf<Int, Int>().withDefault { 0 }.apply {
// the [attempted] logic behind this piece of code here is
// that as we iterate through the list, the 'getOrPut()'
// function will return either the value for the given [key]
// or throw an exception if there is no such key
// in the map. However, since our map was created by
// [withDefault], the function resorts to its `defaultValue` <-> 0
// instead of throwing an exception.
for (e in pile) {
// this simplifies our code and inserts a zero [+1] where needed.
// if (key exists)
// // return its associated value and MOD it:
// case: even -> increment counter
// else -> do nothing
// else if (key dne)
// // insert default value <-> [0] + 1
// ....
// ....
// ....
println(e)
put(e, getValue(e) + 1)
if (getValue(e) % 2 == 0) count++
println(entries)
}
}
return count
}
val n = 5
val ar = "10 10 10 10 20 20 30 40".split(" ").map{ it.trim().toInt() }.toTypedArray()
val result = sockMerchant(n, ar)
println(result)
Output :
10
[10=1]
10
[10=2]
10
[10=3]
10
[10=4]
20
[10=4, 20=1]
20
[10=4, 20=2]
30
[10=4, 20=2, 30=1]
40
[10=4, 20=2, 30=1, 40=1]
3
Pair.kts:3:18: warning: parameter 'n' is never used
fun sockMerchant(n: Int, pile: Array<Int>): Int{
^
Process finished with exit code 0
Explanation :
You looped over "values", which is at start empty, so you never did anything with your code
Even when looping over pile, your incrementation logic didn't go above 1, so the condition was never satisfied and the count was never incremented.
But the main reasoning behind was correct.
I've written two Alloy solutions to the "water pouring puzzle" (Given a 5 quart jug, a 3 quart jug, can you measure exactly 4 quarts?)
My first attempt (specific.als) hardcodes the two jugs as named relations:
sig State {
threeJug: one Int,
fiveJug: one Int
}
It solves the puzzle (finds a counterexample) in about 500ms.
My second attempt (generic.als) is coded to allow for an arbitrary number of jugs and different sizes:
sig State {
jugAmounts: Jug -> one Int
}
It solves the puzzle in about 2000ms.
Is it possible for the generic code, to run as quickly as the specific code?
What would need to be changed?
Specific Model
open util/ordering[State]
sig State {
threeJug: one Int,
fiveJug: one Int
}
fact {
all s: State {
s.threeJug >= 0
s.threeJug <= 3
s.fiveJug >= 0
s.fiveJug <= 5
}
first.threeJug = 0
first.fiveJug = 0
}
pred Fill(s, s': State){
(s'.threeJug = 3 and s'.fiveJug = s.fiveJug)
or (s'.fiveJug = 5 and s'.threeJug = s.threeJug)
}
pred Empty(s, s': State){
(s.threeJug > 0 and s'.threeJug = 0 and s'.fiveJug = s.fiveJug)
or (s.fiveJug > 0 and s'.fiveJug = 0 and s'.threeJug = s.threeJug)
}
pred Pour3To5(s, s': State){
some x: Int {
s'.fiveJug = plus[s.fiveJug, x]
and s'.threeJug = minus[s.threeJug, x]
and (s'.fiveJug = 5 or s'.threeJug = 0)
}
}
pred Pour5To3(s, s': State){
some x: Int {
s'.threeJug = plus[s.threeJug, x]
and s'.fiveJug = minus[s.fiveJug, x]
and (s'.threeJug = 3 or s'.fiveJug = 0)
}
}
fact Next {
all s: State, s': s.next {
Fill[s, s']
or Pour3To5[s, s']
or Pour5To3[s, s']
or Empty[s, s']
}
}
assert notOne {
no s: State | s.fiveJug = 4
}
check notOne for 7
Generic Model
open util/ordering[State]
sig Jug {
max: Int
}
sig State {
jugAmounts: Jug -> one Int
}
fact jugCapacity {
all s: State {
all j: s.jugAmounts.univ {
j.(s.jugAmounts) >= 0
and j.(s.jugAmounts) <= j.max
}
}
-- jugs start empty
first.jugAmounts = Jug -> 0
}
pred fill(s, s': State){
one j: Jug {
j.(s'.jugAmounts) = j.max
all r: Jug - j | r.(s'.jugAmounts) = r.(s.jugAmounts)
}
}
pred empty(s, s': State){
one j: Jug {
j.(s'.jugAmounts) = 0
all r: Jug - j | r.(s'.jugAmounts) = r.(s.jugAmounts)
}
}
pred pour(s, s': State){
some x: Int {
some from, to: Jug {
from.(s'.jugAmounts) = 0 or to.(s'.jugAmounts) = to.max
from.(s'.jugAmounts) = minus[from.(s.jugAmounts), x]
to.(s'.jugAmounts) = plus[to.(s.jugAmounts), x]
all r: Jug - from - to | r.(s'.jugAmounts) = r.(s.jugAmounts)
}
}
}
fact next {
all s: State, s': s.next {
fill[s, s']
or empty[s, s']
or pour[s, s']
}
}
fact SpecifyPuzzle{
all s: State | #s.jugAmounts = 2
one j: Jug | j.max = 5
one j: Jug | j.max = 3
}
assert no4 {
no s: State | 4 in univ.(s.jugAmounts)
}
check no4 for 7
By experience, better performance can be obtained by :
Reducing the size of the search space ( by decreasing the scope, the number of sig and relations, the arity of relations,..)
Simplifying constraints. Try to avoid using set comprehension and quantification as much as possible. As an example, your assertion, no s: State | 4 in univ.(s.jugAmounts) is logically equivalent to 4 not in univ.(State.jugAmounts). Making this tiny change alone in your model has already made the processing of clauses 200ms faster on my end.
EDIT
I came back to your problem during my free time.
Here's the model I used to reach this conclusion
module WaterJugs/AbstractSyntax/ASM
open util/ordering[State]
open util/integer
//===== HARDCODE 2 jugs of volume 3 and 5 resp. comment those lines for generic approach ====
one sig JugA extends Jug{}{
volume=3
water[first]=0
}
one sig JugB extends Jug{}{
volume=5
water[first]=0
}
//==================================================================
abstract sig Jug{
volume: Int,
water: State ->one Int
}{
all s:State| water[s]<=volume and water[s]>=0
volume >0
}
pred Fill(s1,s2:State){
one disj j1,j2:Jug{j1.water[s1]!=j1.volume and j1.water[s2]=j1.volume and j2.water[s2]=j2.water[s1] }
}
pred Empty(s1,s2:State){
one disj j1,j2:Jug{ j1.water[s1]!=0 and j1.water[s2]=0 and j2.water[s2]= j2.water[s1] }
}
pred Pour(s1,s2:State){
one disj j1,j2: Jug{
add[j1.water[s1],j2.water[s1]] >j1.volume implies {
( j1.water[s2]=j1.volume and j2.water[s2]=sub[j2.water[s1],sub[j1.volume,j1.water[s1]]])}
else{
( j1.water[s2]=add[j1.water[s1],j2.water[s1]] and j2.water[s2]=0)
}
}
}
fact Next {
all s: State-last{
Fill[s, s.next]
or Pour[s, s.next]
or Empty[s, s.next]
}
}
sig State{
}
assert no4 {
4 not in Jug.water[State]
}
check no4 for 7
In bonus, here's a visualization of the counter exemple provided by Lightning
Hi I'm trying to follow a tutorial on Ray Wenderlich site
[http://www.raywenderlich.com/76740/make-game-like-space-invaders-sprite-kit-and-swift-tutorial-part-1][1]
so I'm going thru the functions breaking it down so i can get an understanding of how it works I've commented out stuff which i think i understand but this bit has me stumped
thanks for looking
the for loop whats the var row = 1 at the beginning doing ?
I've only ever done for lops like
for Position in 0...9
{
// do something with Position ten times
}
then whats the % in if row %3 mean?
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
hers the rest of the code
func makeInvaderOfType(invaderType: InvaderType) -> (SKNode) // function passes in a enum of atype,btype,ctype and returns sknode
{
var invaderColor: SKColor// variable for the colour
switch(invaderType)// switch statment if we pass in atype we will get red
{
case .AType:
invaderColor = SKColor.redColor()
case .BType:
invaderColor = SKColor.greenColor()
case .CType:
invaderColor = SKColor.blueColor()
default:
invaderColor = SKColor.blueColor()
}
let invader = SKSpriteNode(color: invaderColor, size: kInvaderSize)//variable of a skspritenode with color from switch statement size from vairiabe kinvadersize
invader.name = kInvaderName // name is invader fron let kinvadername
return invader //return the spritenode with color size name
}
func setupInvaders()
{
let baseOrigin = CGPoint(x:size.width/3, y:180) // vairible to hold cgpoint screen size /3 width 180 height
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
{
invaderType = .BType
} else
{
invaderType = .CType
}
let invaderPositionY = CGFloat(row) * (kInvaderSize.height * 2) + baseOrigin.y// varible to hold cgfloat row ? think its the incriment of the for loop times 16 times 2 = 32 plus 180 first time is 212 then 244
/* so if ive got his rightthe sum goes row = 1 kinvadersize.hieght *2 = 32 + baseoringin.y = 180
1 * 32 +180 = 212
2 * 32 + 180 = 392 but its 244
*/
println(row)
var invaderPosition = CGPoint(x:baseOrigin.x, y:invaderPositionY) // varible to hold cgpoint
println(invaderPosition.y)
for var col = 1; col <= kInvaderColCount; col++
{
var invader = makeInvaderOfType(invaderType)// varible that runs function and return the spritenode with color size name????
invader.position = invaderPosition
addChild(invader)
invaderPosition = CGPoint(x: invaderPosition.x + kInvaderSize.width + kInvaderGridSpacing.width, y: invaderPositionY)
}
}
}
If I understand your question correctly, here's the answer. Based on this code:
for var row = 1; row <= kInvaderRowCount; row++ // start of loop
{
var invaderType: InvaderType // varible of atype etc
if row % 3 == 0
{
invaderType = .AType
} else if row % 3 == 1
The first line means:
var row = 1: given a new variable, row, with a value of 1
row <= kInvaderRowCount: as long as the variable row is less than or equal to kInvaderRowCount, keep running the for loop
row++: after each time the loop is run, increment (increase) the value of row by 1
As for the "%", that is the modulo operator. It returns the remainder after a division operation on integer values. So if 7 divided by 3 = 2, with a remainder of 1, then
7 / 3 = 2
7 % 3 = 1
The modulus operator results in an integer. While 1 / 3 = 0.33..., 1 % 3 = 1. Because the remainder of 1 divided by 3 is 1.
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
see also: How Does Modulus Divison Work.
First of all: before you downgrade THIS IS NOT MY HOMEWORK, this question belongs to codingbat or eulerproject or another website. I am NOT asking you to give me a fully completed and coded answer I am asking you to give me some ideas to HELP me.
Later on, I am having a time limit trouble with this problem. I actually solved it but my solution is too slow. It needs to be done within at 0 to 1 second. In the worst case scenario my code consumes more than 8 seconds. If you could help me with some ideas or if you could show me a more accurate solution pseudo code etc. I would really appreciate it.
First input means how many times we are going to process. Later on, user enters two numbers [X, Y], (0 < X < Y < 100000) We need to compute the most frequent digit in the range of these two numbers X and Y. (including X and Y) Besides, If multiple digits have the same maximum frequency than we suppose to print the smallest of them.
To illustrate:
User first enters number of test cases: 7
User enters X and Y(first test case): 0 21
Now I did open all digits in my solution you may have another idea you are free to use it but to give you a hint: We need to treat numbers like this: 0 1 2 3 ... (here we should open 10 as 1 and 0 same for all of them) 1 0 1 1 1 2 1 3 ... 1 9 2 0 2 1 than we show the most frequent digit between 0 and 21 (In this case: 1)
More examples: (Test cases if you want to check your solution)
X: 7 Y: 956 Result: 1
X: 967 Y: 8000 Result: 7
X: 420 Y: 1000 Result: 5 etc.
Here's my code so far:
package most_frequent_digit;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class Main
{
public static int secondP = 0;
public static void getPopularElement(int[] list)
{
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer nextInt : list)
{
Integer count = map.get(nextInt);
if (count == null)
{
count = 1;
} else
{
count = count + 1;
}
map.put(nextInt, count);
}
Integer mostRepeatedNumber = null;
Integer mostRepeatedCount = null;
Set<Integer> keys = map.keySet();
for (Integer key : keys)
{
Integer count = map.get(key);
if (mostRepeatedNumber == null)
{
mostRepeatedNumber = key;
mostRepeatedCount = count;
} else if (count > mostRepeatedCount)
{
mostRepeatedNumber = key;
mostRepeatedCount = count;
} else if (count == mostRepeatedCount && key < mostRepeatedNumber)
{
mostRepeatedNumber = key;
mostRepeatedCount = count;
}
}
System.out.println(mostRepeatedNumber);
}
public static void main(String[] args)
{
#SuppressWarnings("resource")
Scanner read = new Scanner(System.in);
int len = read.nextInt();
for (int w = 0; w < len; w++)
{
int x = read.nextInt();
int y = read.nextInt();
String list = "";
for (int i = x; i <= y; i++)
{
list += i;
}
String newList = "";
newList += list.replaceAll("", " ").trim();
int[] listArr = new int[list.length()];
for (int j = 0; j < newList.length(); j += 2)
{
listArr[secondP] = Character.getNumericValue(newList.charAt(j));
secondP++;
}
getPopularElement(listArr);
secondP = 0;
}
}
}
As you can see it takes too long if user enters X: 0 Y: 1000000 like 8 - 9 seconds. But it supposed to return answer in 1 second. Thanks for checking...
Listing all digits and then count them is a very slow way to do this.
There are some simple cases:
X = 10n, X = 10n+1-1 (n > 0) :
The digits 1 to 9 are appearing 10n + n⋅(10n-10n-1) times, 0 appears n⋅(10n-10n-1) times.
E.g.
10, 99: the digits 1 to 9 are appearing 19 times, 0 appears 9 times.
100, 999: the digits 1 to 9 are appearing 280 times, 0 appears 180 times.
X = a⋅10ⁿ, Y = (a+1)⋅10ⁿ-1 (1 ≤ a ≤ 9):
All digits except for a appears n⋅10n-1, the digit a appears 10n + n⋅10n-1 times.
E.g.
10, 19: all digits except for 1 appear one time, 1 appears 11 times.
20, 299: all digits except for 2 appear 20 times, 2 appears 120 times.
With this cases you can split off the input into sub cases. E.g.
X = 0, Y = 21. Split it up into
X₁ = 0, Y₁ = 9 (special case, but very simple),
X₂ = 10, Y₂ = 19 (case 2),
X₃ = 20, Y₃ = 21 (case 3)
X = 0, Y = 3521. Split it up into
X₁ = 0, Y₁ = 9 (special case, but very simple),
X₂ = 10, Y₂ = 99 (case 1),
X₃ = 100, Y₃ = 999 (case 1),
X₄ = 1000, Y₄ = 1999 (case 2),
X₅ = 2000, Y₅ = 2999 (case 2),
X₆ = 3000, Y₆ = 3521 (case 3)
I left case 3 open. The case looks like X = a⋅10ⁿ, Y = a⋅10ⁿ + b (1 ≤ a ≤ 9, 0 ≤ b < 10ⁿ).
Here you know you get the digit a b-times plus the number of appearances in 0 to b. Since X and Y are n+1 digit numbers, b has n digits, with leading zeros.
The missing parts of case 3 have to be filled by the reader.
I recently did studying stuff and meet up with Donald Knuth. But i didn't found the right algorithm to my problem.
The Problem We have a league with n players. every week they have a match with one other. in n-1 weeks every team fought against each other. there are n/2 matches a day. but one team can only fight once in a week. if we generate an (n/k) combination we get all of the combinations... (assuming k = 2) but i need to bring them in the right order.
My first suggestion was... not the best one. i just made an array, and then let the computer try if he finds the right way. if not, go back to the start, shuffle the array and do it again, well, i programmed it in PHP (n=8) and what comes out works, but take many time, and for n=16 it gives me a timeout as well.
So i thought if maybe we find an algorithm, or anybody knows a book which covers this problem.
And here's my code:
http://pastebin.com/Rfm4TquY
The classic algorithm works like this:
Number the teams 1..n. (Here I'll take n=8.)
Write all the teams in two rows.
1 2 3 4
8 7 6 5
The columns show which teams will play in that round (1 vs 8, 2 vs 7, ...).
Now, keep 1 fixed, but rotate all the other teams. In week 2, you get
1 8 2 3
7 6 5 4
and in week 3, you get
1 7 8 2
6 5 4 3
This continues through week n-1, in this case,
1 3 4 5
2 8 7 6
If n is odd, do the same thing but add a dummy team. Whoever is matched against the dummy team gets a bye that week.
Here is the code for it in JavaScript.
function makeRoundRobinPairings(players) {
if (players.length % 2 == 1) {
players.push(null);
}
const playerCount = players.length;
const rounds = playerCount - 1;
const half = playerCount / 2;
const tournamentPairings = [];
const playerIndexes = players.map((_, i) => i).slice(1);
for (let round = 0; round < rounds; round++) {
const roundPairings = [];
const newPlayerIndexes = [0].concat(playerIndexes);
const firstHalf = newPlayerIndexes.slice(0, half);
const secondHalf = newPlayerIndexes.slice(half, playerCount).reverse();
for (let i = 0; i < firstHalf.length; i++) {
roundPairings.push({
white: players[firstHalf[i]],
black: players[secondHalf[i]],
});
}
// rotating the array
playerIndexes.push(playerIndexes.shift());
tournamentPairings.push(roundPairings);
}
return tournamentPairings;
}
UPDATED:
Fixed a bug reported in the comments
I made this code, regarding the Okasaki explanation
const roundRobin = (participants) => {
const tournament = [];
const half = Math.ceil(participants.length / 2);
const groupA = participants.slice(0, half);
const groupB = participants.slice(half, participants.length);
groupB.reverse();
tournament.push(getRound(groupA, groupB));
for(let i=1; i < participants.length - 1; i ++) {
groupA.splice(1, 0, groupB.shift());
groupB.push(groupA.pop())
tournament.push(getRound(groupA, groupB));
}
console.log(tournament)
console.log("Number of Rounds:", tournament.length)
return tournament;
}
const getRound = (groupA, groupB) => {
const total = [];
groupA.forEach((p, i) => {
total.push([groupA[i], groupB[i]]);
});
return total;
}
roundRobin([1,2,3,4,5,6,7])
P.S.: I put an example with an odd amount, so there is a team doesn't play every round, dueling with undefined, you can customize it the way you want
I made an updated solution for this with reusable functions (inspired by varun):
const testData = [
"Red",
"Orange",
"Yellow",
"Green",
"Blue",
"Indigo",
"Violet",
];
const matchParticipants = (participants) => {
const p = Array.from(participants);
if (p % 2 == 1) {
p.push(null);
}
const pairings = [];
while (p.length != 0) {
participantA = p.shift();
participantB = p.pop();
if (participantA != undefined && participantB != undefined) {
pairings.push([participantA, participantB]);
}
}
return pairings;
};
const rotateArray = (array) => {
const p = Array.from(array);
const firstElement = p.shift();
const lastElement = p.pop();
return [firstElement, lastElement, ...p];
};
const generateTournament = (participants) => {
const tournamentRounds = [];
const rounds = Math.ceil(participants.length / 2);
let p = Array.from(participants);
for (let i = 0; i < rounds; i++) {
tournamentRounds.push(matchParticipants(p));
p = rotateArray(p);
}
return tournamentRounds;
};
console.log(generateTournament(testData));
here is the code in python for those interested :
def makePairing(inputList):
if len(inputList) % 2 == 1:
inputList.append("No Opponent")
pairings = list()
for round in range(len(inputList) - 1):
round_pairings = list()
first_half = inputList[:int(len(inputList)/2)]
second_half = list(reversed(inputList[int(len(inputList)/2):]))
for element in range(len(first_half)):
round_pairings.append((first_half[element], second_half[element]))
pairings.append(round_pairings)
inputList = inputList[0:1] + inputList[2:] + inputList[1:2]
return pairings