Skip to content

Instantly share code, notes, and snippets.

@kaja47
kaja47 / gist:554f62c61f21b0420720
Created May 9, 2014 19:47
minhash vs. HyperLogLog
// min-hash
val fs: Vector[Int => Int] // hash funkce
items map { it => fs map { f => f(it) } } fold (vectorPairwise(min), initialValue = Vector.fill(infinity))
// HyperLogLog
@kaja47
kaja47 / csfd-crawler.php
Created March 12, 2014 01:06
Example crawler using Matcher and AsyncCurl
<?php
use Atrox\Matcher;
use Atrox\Curl;
use Atrox\Async;
$userListMatcher = Matcher::multi('//table[@class="ui-table-list"]//tr', (object) [
'url' => Matcher::single('td/a/@href')->map(function ($x) { return "http://www.csfd.cz$x"; }),
'points' => Matcher::single('td[3]')->asInt(),
'ratings' => Matcher::single('td[4]')->asInt(),
@kaja47
kaja47 / rachel-riley.scala
Last active August 29, 2015 13:55
Contdown's number game solver for all freaks who like me watched too much British panel shows.
sealed trait Tree {
def eval: Option[Int]
}
case class Leaf(n: Int) extends Tree {
override def toString = n.toString
def eval = Some(n)
}
case class Node(op: String, l: Tree, r: Tree) extends Tree {
@kaja47
kaja47 / combinations.scala
Last active December 27, 2015 15:49
Fast array combinations
// genrate all combinations of integers in range from 0 to `len`-1
// fast as fuck
def combIdxs(len: Int, k: Int): Iterator[Array[Int]] = {
val arr = Array.range(0, k)
arr(k-1) -= 1
val end = k-1
Iterator.continually {
arr(end) += 1
if (arr(end) >= len) {
@kaja47
kaja47 / change-count.php
Last active December 26, 2015 11:49
yield examples
<?php
function countChange($amount) {
return cc($amount, 5);
}
function cc($amount, $kindOfCoins) {
if ($amount === 0) return 1;
if ($amount < 0) return 0;
if ($kindOfCoins === 0) return 0;
@kaja47
kaja47 / pearson.scala
Last active October 4, 2016 14:25
Pearson correlation coefficient in scalanlp/breeze
import breeze.linalg._
def corr(a: DenseVector[Double], b: DenseVector[Double]): Double = {
if (a.length != b.length)
sys.error("you fucked up")
val n = a.length
val (amean, avar) = meanAndVariance(a)
val (bmean, bvar) = meanAndVariance(b)
@kaja47
kaja47 / promises-promises.php
Last active December 20, 2015 07:58
You almost can do this in PHP, almost.
<?php
// generators are weaker than monads and this is therefore not possible
// CPS transformation to state machines sucks balls
$usersWhoCommentedOnTheirPosts = run($seqMonad, function () {
$user = (yield allUsers());
$post = (yield $user->posts);
$comm = (yield $post->comments);
if ($comm->author === $comm->author)

Můj problém je jednoduchý: mám pole doublů a potřebuji top-k hodnot a jejich indexů.

Top-k vrátí k největších elementů, které jsou větší než nějaké minimum. Funkce topKEstaimateMin velice rychle odhadne tohle minimum (jednou sekvenčně projde pole a ke cache se chová naprosto ideálně). Odhad nebude skutečné minimum, ale bude o něco menší, tedy vybere víc než k elementů. Ale zároveň garantuje, že nebude větší něž skutečné minimum. Je to tedy dolní mez pro minimum.

Pracuje tak, že rozhazuje elementy do k bucketů (prakticky je to nejbližší mocnina dvou větší než k, protože pak můžu použít maskování bitů, které je mnohem rychlejší než modulo) a počítá jejich maxima. Z těchto maxim pak vezmu minimum, u kterého je garantováno, že je menší nebo rovno než k (nebo více) čísel ze zdrojového pole a v ideálním je poměrně blízko skutečného minima (v mých testech se ukazuje, že pro n=340000 a k=1000, to vrátí minimum pro 6000 čísel, tedy odfiltruje 98% hodnot).

Dá se to dělat taky obráceně,

@kaja47
kaja47 / top-k-magic.scala
Created July 7, 2013 17:44
They said I can't have fast TopK, but I proved them wrong. And they stabbed me in the stomach.
def topKEstaimateMin(arr: Array[Double], k: Int): Double = {
import java.lang.Integer
val upperK = Integer.highestOneBit(k) * 2 // must be higher than k, otherwise can produce wrong minimum
val bits = Integer.numberOfTrailingZeros(upperK)
val mask = (1 << bits) - 1
var i = 0
val maximums = new Array[Double](upperK)
while (i < arr.length) {
val pos = i & mask
val m = maximums(pos)
@kaja47
kaja47 / cache-localtiy-son.scala
Created July 7, 2013 03:18
Cache locality, son!
final class SegmentSumBuffer(val size: Int) {
private val segmentBits = 12 // 4096 elemets per segmen (n * 8 bytes must fit in L1 cache)
private val segments = size / (1 << segmentBits) + 1
private val segmentSize = 8192 // arbitrary number
private val keySegments = Array.fill(segments) { new Array[Int](segmentSize) }
private val valSegments = Array.fill(segments) { new Array[Double](segmentSize) }
private val positions = new Array[Int](segments) // next pos