Martin Ankerl Chunky bacon!! 2012-02-08T19:24:46Z http://martin.ankerl.com/feed/atom/ martinus <![CDATA[Everything here under Creative Commons]]> http://martin.ankerl.com/?p=953 2012-02-05T09:25:51Z 2012-02-05T09:25:51Z Continue reading ]]> I have now put everything on this blog, except otherwise stated, under the Creative Commons Attribution 3.0 Unported License:

Creative Commons License This means you are free

  • to Share — to copy, distribute and transmit the work
  • to Remix — to adapt the work
  • to make commercial use of the work

The only restriction is

  • Attribution — You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).

This is your ticket to get filthy rich from everything I have on my blog without me ever seeing a dime.

]]>
0
martinus <![CDATA[Optimized Approximative pow() in C / C++]]> http://martin.ankerl.com/?p=894 2012-01-26T07:29:26Z 2012-01-25T19:48:39Z Continue reading ]]> Mostly thanks to this reddit discussion, I have updated my pow() approximation for C / C++. I have now two different versions:

inline double fastPow(double a, double b) {
  union {
    double d;
    int x[2];
  } u = { a };
  u.x[1] = (int)(b * (u.x[1] - 1072632447) + 1072632447);
  u.x[0] = 0;
  return u.d;
}


This new code uses the union trick, instead of the weird casting trick I’ve used before. This means that -fno-strict-aliasing is no more required any more when compiling, and it is also a bit faster because one less temporary variables is needed. When you have a little endian machine, you have to exchange u.x[0] and u.x[1]. On my PC, this version is 4.2 times faster than the much more precise pow().

Besides that, I also have now a slower approximation that has much less error when the exponent is larger than 1. It makes use exponentiation by squaring, which is exact for the integer part of the exponent, and uses only the exponent’s fraction for the approximation:

// should be much more precise with large b
inline double fastPrecisePow(double a, double b) {
  // calculate approximation with fraction of the exponent
  int e = (int) b;
  union {
    double d;
    int x[2];
  } u = { a };
  u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447);
  u.x[0] = 0;

  // exponentiation by squaring with the exponent's integer part
  // double r = u.d makes everything much slower, not sure why
  double r = 1.0;
  while (e) {
    if (e & 1) {
      r *= a;
    }
    a *= a;
    e >>= 1;
  }

  return r * u.d;
}

This code is 3.3 times faster than pow(). Writing a microbenchmark is not easy, so I have posted mine here. Here is also a Java version of the more accurate pow approximation.

Any ideas how this could be improved? Please post them!

]]>
0
martinus <![CDATA[Chunky bacon]]> http://martin.ankerl.com/?p=840 2012-02-05T19:31:52Z 2012-01-15T20:21:11Z Continue reading ]]> Since I blog a mixture of health and programmnig, my old tagline May all your work reduce to O(1) just didn’t cut it any more. Fortunately I have a found a perfect replacement:
Chunky bacon!!

This is the perfect combination of both worlds. Unfortunately, only few readers will get that chunky bacon is actually good for your health. Even fewer readers will get that this is actually a famous programming reference. Even fewer readers will get that it is actually both…

]]>
0
martinus <![CDATA[Low Carb High Fat — Big Video Roundup]]> http://martin.ankerl.com/?p=735 2012-02-08T19:24:46Z 2012-01-15T15:08:08Z Continue reading ]]> So you want to get healthy, lose weight, or both? Then the Low Carb High Fat diet might be for you, but please judge for yourself. This page is merely an attempt to collect the most important and interesting talks/presentations about this general topic. In a nutshell, it seems carbohydrates are bad for your body, and fats are good. If you think this is crazy, I invite you to do some research on your own. Educate yourself, your body will thank you.

If you find a video that you think belongs here, please post it here or at the reddit discussion! I will try to keep this page updated.

Shortlink for this page to send to your friends: http://j.mp/lchf

Table of Contents

  1. The Food Revolution – AHS 2011
  2. The Cause of Obesity
  3. Low Carb Explained
  4. Sugar and Starch
  5. Why We All Don’t Get Cancer – Sloan-Kettering
  6. How Bad Science and Big Business Created the Obesity Epidemic
  7. Gary Taubes: Why We Get Fat (Authors@Google)
  8. Low Carb Living
  9. Sugar: The Bitter Truth
  10. The Trouble with Fructose: a Darwinian Perspective by Robert Lustig, MD
  11. “Heart Disease and Molecular Degeneration” by Chris Masterjohn
  12. Enjoy Eating Saturated Fats: They’re Good for You. Donald W. Miller, Jr., M.D.
  13. The Paleo Diet – Robb Wolf answers questions
  14. Fat Head

The Food Revolution – AHS 2011

Good introduction that explains why carbohydrates are bad for you, and fat is good. Studies show that saturated fat is actually safe and healthy, too much carbohydrates can make you fat and sick. Dr. Eenfeldt is from Sweden, and has gathered quite a following for LCHF (Low Carb High Fat). 54 minutes video.

The Cause of Obesity

Robert H. Lustig is a medical doctor, researcher and expert on obesity, with an interesting example: “You eat 2000 calories a day, you burn 2000 calories a day, you feel good; normal day. You will not gain or lose weight, you stay the same because you burn what you eat, fine. Now let’s do a little experiment: Every time you reach for food, I will pump you full of extra insulin. You start your day, and eat just the 2000 calories like before. But now, because of the excess insulin, 500 of these 2000 go straight to body fat. You are now 500 calories heavier–you ate 2000 but you lost 500 to your fat. How many calories do you have left to burn? 1500. But your body wants 2000! What do we call the state when your body has fewer calories than it wants to burn? Starvation. You feel crappy, tired, lazy, don’t want to exercise, and hungry. So you will go eat the extra 500 to feel better. You go to the doctor and ask: “Doctor, how come I am so fat?” and the doctor says: “I know why you are fat, you are lazy and eat too much.” That’s because they are only looking at the outcome, not the cause. The cause was me, injection you with insulin. The outcome was a change in your behavior.”

Low Carb Explained

Dr. Mary Vernon, MD, is one of the world’s foremost experts on treating obesity and diabetes with low carbohydrate nutrition. “The job of insulin is to stop fat burning and enhance fat storage”. So all you have to know is how your body controls insulin, its that easy. Unfortunately, food companies want to sell starch and sugar, because it makes you hungry and eat more. A 32 minutes video.

Sugar and Starch

An outtake from the documentary Fat Head. Some interesting quotes from it: “Sugar and starch are basically the same, because starch is just glucose molecules formed into long chains. The body immediately splits it up; starting in your mouth so in essence you are just eating sugar.”

“People say “Well, there are complex carbohydrates” which is true, but as soon as it hits the gastrointestinal tract, it breaks down into glucose and basically blood sugar. That’s why blood sugar rises quickly with bread, potatoes, rice, and all these starchy foods. Even complex carbohydrates run the blood sugar up almost as quickly as sugar.”

“The amount of sugar you have in your blood is a little bit less than one teaspoon. One teaspoon dissolved in your entire blood volume gives you normal blood sugar.

“Sugar is actually quite toxic. Insulin has many jobs, but the most critical is to keep the blood sugar in a really narrow range to keep us alive. Everything else is secondary. So a lot of it is put into fat cells. Insulin does not care if you get fat, it just tries to bring your blood sugar down.”

Why We All Don’t Get Cancer — Sloan-Kettering

Craig B. Thompson, President and CEO of Memorial Sloan-Kettering Cancer Center, discusses new ways to think about cancer and how cancer arises in human beings. This is a very interesting talk from February 2011. First he explains how cells function in a multicellular organism, why cells have to be told how much to eat every day, how cancer develops by first causing mutations in the glucose uptake, why once a cell can eat glucose it does not think about dying which enables mutations, etc. “To truly eliminate cancer, we have to eliminate or better understand what overeating, obesity and diabetes is all about.”. He posts this question at the end of the talk: Overeating which types of foods increases the risk of cancer?

  1. Fats
  2. Carbohydrates
  3. Proteins

It matters a lot where your calories come from. We now have good evidence that if you overeat with fat, you don’t increase your cancer risk at all. If you overfeed somebody with carbohydrates, you dramatically increase the cancer risk. Protein is halfway in between.

How Bad Science and Big Business Created the Obesity Epidemic

David Diamond, Ph.D., of the University of South Florida College of Arts and Sciences shares his personal story about his battle with obesity. Diamond shows how he lost weight and reduced his triglycerides by eating red meat, eggs and butter. You can download the slides here. In over 100 slides he explains how fat people how are good for business, how ridiculous bad the science is on which mainstream guidelines are based, how cholesterol is a huge fraud, how butter consumption does not correlate with heart disease, etc. According to Dr. Andreas Eenfeldt, he is almost right, except for one thing: Diamond claims that eating high fat do not raise cholesterol, but on average it does. However, it is mainly the good cholesterol, the HDL, that increases which means that your risk of heart disease is a lot lower.

Gary Taubes: Why We Get Fat (Authors@Google)

Gary Taubes, author of Why We Get Fat: And What to Do About it (2011) and Good Calories, Bad Calories (2007). He is a scientific journalist who has collected and analyzed a huge amount of studies to find out what actually makes people healthy or sick. Taubes explains why “calories in calories out” is a true but useless explanation for weight regulation, why exercise might not make you thin, why practicing energy balance is impossible, and a lot more. Important takeaway lessons are: Lesson #1: Fat is stored as triglycerides in the body’s fat tissue. It is too big to get out, so your body has to break it up first. Lesson #2: It is insulin that puts fat into your tissue, and it is insulin that suppresses fat mobilization. So if you want to get fat out of your tissue, you have to lower your insulin. Lesson #3: Carbohydrate is driving insulin is driving fat. Fat is the one nutrient that does not stimulate insulin secretion, protein does.

Gary held a similar lecture at Wallnut Creek Library, and in the last section he answers some very interesting question about cancer research. Insulin seems to be linked with cancer and has ties with Alzheimer’s disease. Several cancer researcher are on an Atkins diet not because they want to be slim, but because they do not want to get cancer.

Low Carb Living

Dr Stephen Phinney, MD, PhD knows more about this than almost anybody. He has researched adaptation to very low carb diets (and exercise) for a long time. Here he shares this knowledge about ketosis, as well as insights from traditional cultures who never ever ate a lot of carbs. He has stayed on a ketogenic diet for more than 6 years, with 25 to 50 grams of carbs a day, which is 5% of his daily calories. He argues that you should consume protein in moderation, because high protein intakes reduces ketosis. Not as much as carbohydrates, but still. 75% to 80% of his daily energy comes from fat.
Many people think of Atkins diet (Interview with Dr Eric Westman: part 1, part 2) as a high protein diet, but this is not true: when you look at the induction phase of Atkins, they might eat 1400 calories a day but they might burn 3000 calories a day. So the other half comes from body fat. When you look at what’s on the person’s plate, 600 to 800 of the 1400 calories comes from protein, that looks like a high protein diet. But that’s only what the mouth sees! In reality it is a moderate protein, high fat diet since the other half energy is coming from internal body fat. Once you get to maintainance–meaning you are not burning any more body fat–if you keep eating low carb and low fat, you will have to eat a whole lot of protein. (1400 calories of protein are about 1kg / 2.2 pounds of meat). At that level many people would feel sick. It would cause weakness, fatigue, and it your body will not get into ketosis which means now you have lost your easy access to fat. To make a sustainable low carb diet, you have to keep protein moderate, carb low; and the only other energy source is fat.

Sugar: The Bitter Truth

Robert H. Lustig, MD, UCSF Professor of Pediatrics in the Division of Endocrinology, explores the damage caused by sugary foods. He argues that fructose (too much) and fiber (not enough) seem to be cornerstones of the obesity epidemic through their effects on insulin. Very long and detailed video, why mostly about why high fructose corn syrup (or fructose to be more general) is very bad for your body. A 1 hour 29 minutes presentation, with almost 2 million views.

The Trouble with Fructose: a Darwinian Perspective by Robert Lustig, MD

Robert Lustig’s talks about the reason for the obesity epidemic. There is a reddit discussion about the video, where user moozilla has extracted the slides.

The evolutionary explanation is a mismatch between our environment and our biochemistry. When a normal kid eats a cookie, it will get a “sugar high”, it has now lots of energy and the body wants to get rid of it. When an obese kid eats a cookie, it does not get the sugar high because their leptin is not doing what it is supposed do. That is called leptin resistance.

Fructose induces insulin resistance which then induces leptin resistence. Two different paradimes, when you put them together you got a problem. He speculates that this insulin resistance has evolved because it has an evolutionary advantage: Imagine harvest time. All the fruit is lying on the ground just waiting for you. And what comes after that? Winter! Four months of absolutely no food. Polar bears have hibernation, we don’t; we have the next best thing: seasonal insulin resistance. When fructose comes in and induces the insulin resistance and blocks that leptin, it lets you gorge, put on more adipose tissue, so that you can make it through winter.

The problem is that nowadays fructose is available any time and everywhere, and it is unopposed by fibre which could mitigate it’s effect.

“Heart Disease and Molecular Degeneration” by Chris Masterjohn

Slides are available here. We have a cholesterol war: one side says cholesterol is bad, the other says it isn’t. Between these two fronts, what is the truth? Chris takes a mixed stance. This is an in very scientific analyzation of the science behind the claims.

The abstract states that atherosclerosis is actually trying to protect the lining of the blood vessel from toxic waste generated by the degeneration of vulnerable lipids. The key to preventing heart disease according to the new paradigm is preventing the molecular degeneration in the first place.

So, what to do? Eat your vegetables. Eat omega 3 rich foot. Get antioxidants.

Enjoy Eating Saturated Fats: They’re Good for You. Donald W. Miller, Jr., M.D.

Dr. Miller is a professor of surgery, cardiothoracic division, Univ. Washington. He starts his talk with the classic assumption: According to the lipid hypothesis, saturated fat causes high blood cholesterol, which causes atherosclerosis which in turn causes coronary heart disease. He follows with an overview and history of fat and health. In his work he has followed the general advice to recommend a low fat diet to his patients and follow the food pyramid. He put them on a very low fat (ornish) diet. To quote Dr. Miller: “I was wrong“.

Omnivores do not develop atherosclerosis when fed cholesterol. In his famous study, Ancel Keys selected 6 out of 22 countries and ignored the 16 other countries because they did not fall in line with his desired graph. In fact it turns out that people who have the highest saturated fat in their diets have the lowest risk of heart disease. Lots of native tribes eat mostly saturated fat. The mother milk has 45% saturated fat.

The hunter-gatherer diet: our ancestors consumed high amounts of animal food, prefered the fattest parts (organs, tongue, bone marrow, brain), and low amount of carbs from plants (seeds, nuts, roots, tubers, bulbs, wild fruits–no sugars, starches and grains, corn, potatoes, rice, wheat, beans).

The European Cardiovascular Disease Statistics 2005 shows an inverse correlation with fat consumption and the rate of heart disease. Multiple other recent studies show how saturated fats are good for you.

“Blaming cholesterol for atherosclerosis is like blaming firemen for the fire they are here to put out”.

The Paleo Diet – Robb Wolf answers questions

Robb Wolf has a background as a biochemist and is the author of the book The Paleo Solution – The Original Human Diet. In this video he answers a lot of user questions about the paleo diet. The next section has all the questions linked directly to the answer in the video:

What is the paleo diet? · What do you say to convince people interested in trying the paleo diet? · What are the short and long-term benefits of the paleo diet? · How long should one try to paleo to see results? · Should individuals trying to lose weight on a paleo diet be worried about calorie intake? · What are possible long-term negative effects of following paleo diet? · What are the best snacks on the paleo diet? · How does alcohol figure in the paleo diet? · What does the paleo diet say about carb intake? · What are some example paleo breakfast/lunch/dinner meals? · What concerns are there about modern food quality when eating paleo foods? · What non-dietary recommendations do you have for people wanting to be healthier? · Is it possible to eat paleo on a frugal budget? · What effect does paleo have on inflammatory diseases? He has a long answer covering obesity, diabetes, etc. · What effects would paleo have on pregnancy? · What advice do you have for vegetarians for eating healthier? · What about cholesterol, isn’t all that fat bad for you? · What does higher protein animal meat consumption have to do on the bodies pH level? · What about all that meat causing colon cancer? · What about the claim that caveman lived nasty brutish short lives? · Exercise: how valuable is the concept of carb loading? · What do you envision the future of the paleo diet? · Could society support a completely paleo culture? · To what degree are measurements of healthy lifestyle blood lipids, micro nutrients etc. skewed towards a neolithic baseline? · What should we be teaching about diets in schools? · What do you like talking about at corporate events?

Fat Head

Fat Head is a documentary by Tom Naughton and analysis of Super Size Me, how the US dietary guidelines have been created and all the baloney behind it. In my opinion, if you have seen the above videos you do not get any new information from this movie. But it is probably more easily digestible. It has lots of interviews with nutrition experts who convincingly argue for meat and fat.

Updates to this page

Whenever I watch a video that adds new, interesting information, I will add it. Please post or send me links if you think I have forgotten an important addition.

  • 2012/02/04 — Added “The Paleo Diet – Robb Wolf answers questions”, lots of good question and answers about the paleo diet.
  • 2012/01/28 — Great video from W. Miller about saturated fats added.
  • 2012/01/28 — Add video “Heart Disease and Molecular Degeneration” by Chris Masterjohn which is about cholesterol and atherosclerosis.
  • 2012/01/28 — Added link to Gary Taube’s discussion, talking about cancer and Alzheimer
  • 2012/01/22 — Added “The Trouble with Fructose”, which has an interesting explanation of why we have insulin resistance.
  • 2012/01/18 — added shortlink http://j.mp/lchf, change intro text a bit
  • 2012/01/18 — Added Table of contents
  • 2012/01/17 — replaced Gary Taubes’ interview with his full presentation
  • 2012/01/16 — added movie “fat head”
]]>
5
martinus <![CDATA[Relative Risk for Dummies]]> http://martin.ankerl.com/?p=739 2012-01-26T07:31:34Z 2012-01-06T22:53:30Z Continue reading ]]> I read a lot of health related studies, and most contain in their conclusion a statistical description of the result. To be able to draw valid conclusions for oneself it is very important to understand what all the numbers mean. I have recently learned all that, so here is an example together with an explanation:

The multivariate relative risk of gout among men in the highest quintile of meat intake, as compared with those in the lowest quintile, was 1.41 (95 percent confidence interval, 1.07 to 1.86; P for trend=0.02)
— from Purine-rich foods, dairy and protein intake, and the risk of gout in men, 2004.

A more understandable translation of the above is this:

For the 20% who eat the most meat, the probability of getting gout is 1.41 times (41%) higher than the probability for the 20% who eat the least meat. (The number of participants in the study is large enough to say that with 95% probability the populational (real) mean relative risk is between 1.07 and 1.86, with 1.41 being the best estimate within the range. There is a 2% probability that the whole claim is baloney and all this just happened by chance.)

As posted by jt512: The information in the parentheses is indeed important. 1.41 is the best “point estimate” of the relative risk, given the data. However, the estimate is subject to statistical uncertainty. The 95% confidence interval (CI) quantifies that uncertainty. It is an interval estimate of the relative risk, in the sense that there is a 95% chance that the true relative risk is in the interval.

Wide confidence intervals imply that the point estimate is highly imprecise, or uncertain. The given CI, 1.07–1.86, is quite wide. The lower bound is barely above a relative risk of 1, which would mean no effect of meat intake on risk of gout, and the upper bound is close to 2, which would mean that the risk in the highest quintile is double that in the lowest.

Finally, the P for trend shows that the data are weakly statistically significantly consistent with a linear trend in relative risk across quintiles. Statistically significant, because the p-value is less than 0.05; weakly, because it isn’t much lower than 0.05. You should look at the point estimates of the relative risks for each quintile and decide for yourself whether there appears to be a linear trend from quintile to quintile. Lack of a linear trend would tend to undermine a causal role for meat in the development of gout.

Voilá, now go and read some papers!

Sources: Wikipedia Relative risk, Forum post “P for trend”, Wikipedia Confidence interval, my reddit question.

]]>
0
martinus <![CDATA[Health & Software Engineering]]> http://martin.ankerl.com/?p=725 2012-01-04T21:39:28Z 2012-01-04T21:25:18Z Continue reading ]]> One of my main interest apart from software development is health, mainly nutrition but also exercise. I will try to systematically collect my findings and write a health related blog post from time to time.

Keep in mind that I usually have no idea what I am talking about, I have not any medical background. I just try to collect and organize evidence that I am finding.

So, from now on expect some posts about stuff that might make you healthy, loose weight, gain weight, live longer, or die instantly ;)

]]>
0
martinus <![CDATA[Quickly Solving the “Instagram Engineering Challenge: The Unshredder”]]> http://martin.ankerl.com/?p=676 2011-11-20T08:07:41Z 2011-11-15T20:39:47Z Continue reading ]]> Today I have read about the Instagram Engineering Challenge: The Unshredder, and decided to give it a try. The task is simple to explain: Create a program that can unshred this image (do not try the challenge on this image, try the original PNG source instead!):

I have postet here that I think I can solve it in 2 hours, and got some downvotes for that; so I have decided to really give it a try. Long story short, it took me about 2 hours and 35 minutes.

Before I started developing, I made some quick assumptions to simplify things:

  • I want to code it in Ruby, this is the language where I am most productive.
  • I can assume the size of the stripes is well known, and I have hardcoded this size.
  • The image can be converted to RAW with an external tool, and written into RAW.
While coding I timed myself, and created a little timeline of my trials and errors. Since I wanted to finish as quickly as possible, the code is very ugly: no tests, some hardcoded constants, etc.

Code

Without further ado, I give you the code:

# 0:08 - how to read binary files...
# 0:14 - index RGB values
# 0:21 - difference calculation seems to privide a reasonable number
# 0:25 - create all pairings of each row (too slow: need to use logic for all slices)
# 0:30 - create all pairings
# 0:31 - sorted pairings
# 0:35 - copy and number image to mspaint to verify
# 0:36 - bugfix, wrong slice row calculation
# 0:48 - getting stuck with combining pairs
# 1:03 - recombining
# 1:14 - thinking about how to ensure not to combine invalid groups (duplicates!)
# 1:33 - got first reasonable order. Hopefully the correct order!!
# 1:47 - wrote first image, wrong order
# 1:53 - got an almost correct image! one slice was aligned wrong.
# 1:58 - no luck with grayscale
# 2:28 - damn black-white skyscraper!
# 2:29 - SUCCESSSS!!!!!!
#
# time not measured: I thought about the problem about 5 minutes before starting hacking.
# So my time is probably about 2:34.
class Img
	attr_reader :w, :h, :slices
	def initialize
		# unpack as 8bit unsigned chars
		@d = IO.binread("TokyoPanoramaShredded.raw").unpack("C*")
		@w = 640
		@h = 359
		@slices = 20
		@sw = @w / @slices
	end

	def write(sorted)
		data = @d.dup
		source_slice = 0
		sorted.each do |target_slice|
			# copy one slice
			@sw.times do |w|
				@h.times do |h|
					target_idx = idx(w + @sw * source_slice, h)
					source_idx = idx(w + @sw * target_slice, h)
					data[target_idx] = @d[source_idx]
					data[target_idx+1] = @d[source_idx+1]
					data[target_idx+2] = @d[source_idx+2]
				end
			end
			source_slice += 1
		end

		File.open("out.raw", "wb") do |f|
			f.write data.pack("C*")
		end
	end

	def idx(x, y)
		(y * @w + x) * 3
	end

	# top left is 0, 0
	def rgb(x, y)
		i = idx(x, y)
		[@d[i], @d[i+1], @d[i+2]]
	end	

	# calculate sum of difference between r, g, b of two columns
	def difference(x1, x2)
		diff = 0
		@h.times do |y|
			# find best in range. This is required because otherwise the black syscraper fucks things up.
			lower = y - 15
			lower = 0 if (lower < 0)

			upper = y + 15
			upper = @h-1 if upper >= @h

			best = 1e100
			lower.upto(upper) do |r|
				v = 0
				rgb1 = rgb(x1, r)
				rgb2 = rgb(x2, r)

				d = rgb1[0] - rgb2[0]
				v += d*d
				d = rgb1[1] - rgb2[1]
				v += d*d
				d = rgb1[2] - rgb2[2]
				v += d*d

				best = v if (v < best)
			end
			diff += best
		end
		diff
	end

	def slice_start_idx(s)
		@sw * s
	end

	def slice_end_idx(s)
		@sw * s + @sw - 1
	end
end

# calculate
img = Img.new

# create ALL pairings.
slices = 20
pairs = []
slices.times do |s1|
	slices.times do |s2|
		next if s1 == s2

		pairs.push [img.difference(img.slice_end_idx(s1), img.slice_start_idx(s2)), [s1, s2] ]
	end
end

def add_to_group(combined, new_group)
	# create array of fixed numbers
	taken_numbers = {}
	taken_left = {}
	taken_right = {}
	combined.each do |group|
		group[1..-2].each do |x|
			taken_numbers[x] = true
		end
		taken_left[group.last] = true
		taken_right[group.first] = true
	end

	was_found = false
	combined.each do |group|
		next if was_found
		if (group.last == new_group.first)
			# insert at back
			was_found = true
			new_group.delete_at(0)
			if taken_numbers[new_group.last] || taken_left[new_group.last] || new_group.last == group.first
				return
			end
			new_group.each do |x|
				group.push x
			end
		elsif (group.first == new_group.last)
			# insert at front
			was_found = true
			new_group.pop
			if taken_numbers[new_group.first] || taken_right[new_group.first] || new_group.first == group.last
				return
			end
			new_group.reverse.each do |x|
				group.insert(0, x)
			end
		end
	end
	if !was_found
		cf = combined.flatten
		new_group.each do |x|
			was_found = was_found || cf.index(x)
		end
		if !was_found
			combined.push new_group
		end
	end
end

# sort, lowest first
pairs.sort!

# create combinations.
# combined has an array of all correspondences.
combined = []
pairs.each do |diff, new_group|

	# insert new group
	add_to_group(combined, new_group)

	# try to recombine everything, until nothing changes any more
	was_recombined = true
	while was_recombined
		new_combined = []
		combined.each do |group|
			add_to_group(new_combined, group)
		end
		was_recombined = combined.size != new_combined.size
		combined = new_combined
	end

	if (combined.size == 1 && combined[0].size == img.slices)
		# we got everything! Write output image.
		img.write(combined[0])
		exit
	end
end

Result

Here is the result I got with this code:

Algorithm

In hindsight, the algorithm combines two ideas: Hierarchical Agglomerative Clustering, and a quick and dirty novel distance-metric that defines how “good” a pairing is.

The hierarchical agglomerative clustering is a bit difficult to code, because there are a lot of corner cases when you are allowed to combine pairings and when not. I am not sure if my code is correctly, this should be recoded without time pressure.

The first version of the distance metric was very simple: calculate the sum of the quadratic differences between the two neighboring pixels when two slices are put together. Unfortunately this does not work for the slices with skyscraper that has black-white stripes: here lots of pixels are white on the left side, but black on the right side since the building is just slightly tilt. After realizing this problem, the solution is simple: for each pixel, find the best matching pixel of the other slice within a certain range. Through trial and error I have chosen +-15 pixels, and finally got the correct image.

Happy hacking,
Martin

]]>
5
martinus <![CDATA[Here is a quick list of application…]]> http://martin.ankerl.com/2011/10/13/here-is-a-quick-list-of-application 2011-10-13T08:24:45Z 2011-10-13T08:15:01Z Continue reading ]]> Here is a quick list of applications I regulary use just in case my computer crashes and I have to reinstall everything so I don’t have to find everything again.

Windows apps

Chrome Extensions

Development Helpers

Android

]]>
0
martinus <![CDATA[Single N-Back]]> http://martin.ankerl.com/?p=638 2012-01-26T07:32:13Z 2011-09-30T13:28:33Z Continue reading ]]>

I have just created my first Android app. It is a simple game, called Single N-Back. It has been shown in multiple studies that this game can improve your fluid intelligence.

You can get it here:

Game Rules

The game rules are very simple:
You are shown a sequence of numbers and your task is to click the button if you see the current number matches the one from N steps earlier in the sequence.

For example, in 2-Back, when you get the sequence

5, 3, 0, 4, 2, 8, 9, 1, 9

you should press the button because the currently showen numer 9 is the same as the number shown 2 steps back.

You start with 2-Back, and if more than 80% is correct, you can unlock the next N-back level.

Screenshot

Here are some screenshots of the extremely ugly clean user interface:



References

Since I have not made this test up by myself, here are some papers that explain the validity that that kind of game actually improves fluid intelligence:

Have fun!

]]>
1
martinus <![CDATA[Download Bitcoin Logos]]> http://martin.ankerl.com/?p=607 2012-01-26T07:32:25Z 2011-06-13T08:05:38Z Continue reading ]]> I have recently joined the bitcoin network, and generated PNG images from these excellent bitcoin vector graphics. I have extracted all relevant images, and converted each one into a PNG with transparancy, and in 60, 90, 300, and 600 DPI. All PNGs are recompressed with optipng -o9 to be as small as possible.

Download

The zip file contains these images in 60, 90, 300, and 600 DPI:

This work is in the Public Domain.

If you like this, feel free to donate a few coins to 16fcc4ui1pxW14JteSLZNpaBQ3D45YJ4qc

]]>
0