Being the good capitalist, I thought to myself, why not have ads at the bottom of the page? if what the reader reads is interesting, and they read it in totality, I doubt that they'd mind a simple little ad at the bottom of the page.
So it began, going through the simple few clicks to request the permission to put ads on this blog. Things went as smooth as butter, I must admit. Within a day it was approved! All that was left was to agree to the TOS and finalize what would be presented and how.
As you may notice, there are no ads at the bottom. The TOS has a new frightening set of clauses that I have not yet encountered before. That of various clauses surviving indefinitely even after use of the service terminates.
Typically, I would see a timeframe on the survival, a few years at most. And that is on NDAs that I've signed with previous employers.
It may be argued that the ads service is different - that it does offer a way to interact with various entities where abuse would lead to extra money for whoever benefits from placing the ad. Sure.
However, everything is becoming a service. Look at Photoshop - you just rent it. Same for the developer tools from Apple. Many things that you used to indefinitely license for a single large sum are being rented on a monthly basis.
MMOs, one of gamings rented games, can be abused like Google ads to make money. These games typically have local economies and some people will pay real money for what others picked up over long periods of play. Farming for gold pops to mind. Should a video game have a contract with clauses that indefinitely survive termination?
For legal purposes, it is easy to assume that anything that is done over the Internet is logged. Every conversation, every photo. Be it by the state (see the NSA insanity) or by individual providers (wasn't it reddit that said they can't resist handing logs to suits?)... of course this survival is used to ensure that if something sketchy appears after termination, it can be caught and dealt with.
But back to the issue - can the survival of termination be abused? Could it ever become a boon years down the road as companies go back to these old contracts and try to find any reason to extract funds from old users? I'm not implying any company would do this, but the door could very well be opened at some point.
Or so I believe. Reading these myriad of software EULAs and TOS just bore me to death. And given I'm not a lawyer, I'm sure I've misread a few as I sometimes read clauses multiple times to understand an English that, since it leaves no room to interpretation, can be quite dense.
But typically these end. Mor can be terminated if I got the gist wrong during the first reading. This one doesn't forgive.
On a side-note, I can completely understand why no-one reads these things. They are long, and typically can be summarized as "we are not responsible for anything (nor have any obligation towards you), you are responsible. Oh, and give us money if it's a paid service!"...
Monday, September 15, 2014
Sunday, September 14, 2014
Aren't games counter productive?
For the longest time, I tried to reign in my desire to play games so I may be productive at other things. The problem was, no matter how much control I exerted over myself, there was not net increase in productivity.
Then it dawned upon me: I'm a Sim. There's a progress bar that craves the entertainment provided by video games. And that bar was empty.
So I binged, and played about 14 hours of a game in two days. By the end of it, I was fed up, my meter completely filled, I could then do something else such as work on a web comic. Read, work on a web comic and be happy about it, laughing as the details came together.
It seems that any rhetoric that advocates for anything in the extreme is worrisome. A balanced life requires play in addition to work. And work can't proceed as efficiently until neglected needs are satiated.
That's my theory, and I'm sticking to it. Mainly since it makes me happier. :)
It seems that any rhetoric that advocates for anything in the extreme is worrisome. A balanced life requires play in addition to work. And work can't proceed as efficiently until neglected needs are satiated.
That's my theory, and I'm sticking to it. Mainly since it makes me happier. :)
Thursday, September 11, 2014
Digging a bit further into SpriteKit
A few throw-away prototypes later, and a few things about SpriteKit have become apparent to me.
First -- SpriteKit is highly optimized for image data. That is -- sprites. It is very efficient, put your images in a ".atlas" folder and a texture atlas is built reducing your costly draw calls from dozens (or hundreds depending on your app) to one.
Caveat, that is what SpriteKit does best.
As of writing, a text node will defer to core text Core text will create a texture. That will be slapped onto, what I guess is, an SKSpriteNode. Each text element will incur an additional draw call (even if the text is duplicated - each duplicate will make a new texture. Copying the SKTextNode results in a copy of the texture as well). For a simple HUD, this is perfectly acceptable. I dreamt of a text adventure recently, and SpriteKit would need a bitmap font rendered as SKSpriteNodes even though another framework would be just as good.
The other is drawing filled rects. My best guess is that they are there as placeholders for an actual image-based sprite object. They too don't batch that well together, which did surprise me.
How to track the draw calls? Two ways. One is to do a frame capture while the application is running on device. The other, which I find more convenient, is to set the "showDrawCount" property of the "SKView" to true. Turning on that property was an eye opener.
If we return to the colour-based SKSpriteNodes, be sure to give them a separate zPosition so they blend properly with the other nodes. I have noticed that the drawing order differs when batching becomes possible.
Speaking of "zPosition"; it is safe to assume that each "zPosition" will result in an additional draw call. The furthest are drawn first in one call, the nearer in subsequent call. The mental model that I create for myself is that of creating a bin for each "zPositon" and dispatching each bin at the end.
Before making an image for each possible colour combination, tinting does not affect the number of draw calls. If you were a stubborn person, you could make a white rectangle, create a sprite, and tint it to your heart's desire.
Notice that I have not delved into physics. None of my little experiments needed (sophisticated) physics so far hence I can't comment on how that part of SpriteKit behaves.
Overall, I'm actually quite happy with SpriteKit. The caveats I mention are minimal. Implementing (or finding an implementation of) a bitmap font for SpriteKit is rather trivial with building the font being the time consuming part. And as mentioned, coloured blocks can be simulated with flat textures.
And, in most real-world use-cases, I would guess that the caveats I mention are neglible. For example, when will you display 100 SKLabelNodes? Or do heavy pixelation with 10,000 SKSpriteNodes?
First -- SpriteKit is highly optimized for image data. That is -- sprites. It is very efficient, put your images in a ".atlas" folder and a texture atlas is built reducing your costly draw calls from dozens (or hundreds depending on your app) to one.
Caveat, that is what SpriteKit does best.
As of writing, a text node will defer to core text Core text will create a texture. That will be slapped onto, what I guess is, an SKSpriteNode. Each text element will incur an additional draw call (even if the text is duplicated - each duplicate will make a new texture. Copying the SKTextNode results in a copy of the texture as well). For a simple HUD, this is perfectly acceptable. I dreamt of a text adventure recently, and SpriteKit would need a bitmap font rendered as SKSpriteNodes even though another framework would be just as good.
The other is drawing filled rects. My best guess is that they are there as placeholders for an actual image-based sprite object. They too don't batch that well together, which did surprise me.
How to track the draw calls? Two ways. One is to do a frame capture while the application is running on device. The other, which I find more convenient, is to set the "showDrawCount" property of the "SKView" to true. Turning on that property was an eye opener.
If we return to the colour-based SKSpriteNodes, be sure to give them a separate zPosition so they blend properly with the other nodes. I have noticed that the drawing order differs when batching becomes possible.
Speaking of "zPosition"; it is safe to assume that each "zPosition" will result in an additional draw call. The furthest are drawn first in one call, the nearer in subsequent call. The mental model that I create for myself is that of creating a bin for each "zPositon" and dispatching each bin at the end.
Before making an image for each possible colour combination, tinting does not affect the number of draw calls. If you were a stubborn person, you could make a white rectangle, create a sprite, and tint it to your heart's desire.
Notice that I have not delved into physics. None of my little experiments needed (sophisticated) physics so far hence I can't comment on how that part of SpriteKit behaves.
Overall, I'm actually quite happy with SpriteKit. The caveats I mention are minimal. Implementing (or finding an implementation of) a bitmap font for SpriteKit is rather trivial with building the font being the time consuming part. And as mentioned, coloured blocks can be simulated with flat textures.
And, in most real-world use-cases, I would guess that the caveats I mention are neglible. For example, when will you display 100 SKLabelNodes? Or do heavy pixelation with 10,000 SKSpriteNodes?
Wednesday, September 10, 2014
Return to Class
It has been over 5 years since I last attended a lecture within a formal class setting. Lately, some classes in mathematics have gotten my attention, and since I don't care about the degree anymore, why not just sit in and enjoy the show?
There were two classes that I requested to sit in, and the professors were very kind and said I was welcome as long as I didn't add any work. Fair.
Not caring whether I passed or failed, I opted to go to the more advanced course first. In this class, the students were silent and respected the professor. It was also a challenging class, my mind needed to work quite a bit to follow what was being said.
Even though I could follow if I put in the effort, work was looming over me so I conceded and opted to try the lower-level class. The culture was completely different. Throughout I heard other students talking, playing games, navigating Facebook, eating lunch, questioning the professor... (the prof knew his stuff inside out). There was a sense of boredom, as though similar material has been seen over and over again (set theory is, admittedly, kind of basic -- and certain concepts can be seen in other classes such as linear algebra). I felt bad for the students who just sat there playing your colour-matching game-du-jour; they would learn just as much sitting outside (it was this high-school-esque forced attendance rather than this "I wish to learn" voluntary attendance.
Then came the stark realization; I'm better off listening to the lectures that are put out by the major universities. Even though I enjoy having forced times, these past few times I went to the lectures my mind wasn't thinking of math but of algorithms.
And then my thirst for knowledge would follow my work habits and be satiated when my mind is focused on the subject.
Since I don't care about grades.... why not?
There were two classes that I requested to sit in, and the professors were very kind and said I was welcome as long as I didn't add any work. Fair.
Not caring whether I passed or failed, I opted to go to the more advanced course first. In this class, the students were silent and respected the professor. It was also a challenging class, my mind needed to work quite a bit to follow what was being said.
Even though I could follow if I put in the effort, work was looming over me so I conceded and opted to try the lower-level class. The culture was completely different. Throughout I heard other students talking, playing games, navigating Facebook, eating lunch, questioning the professor... (the prof knew his stuff inside out). There was a sense of boredom, as though similar material has been seen over and over again (set theory is, admittedly, kind of basic -- and certain concepts can be seen in other classes such as linear algebra). I felt bad for the students who just sat there playing your colour-matching game-du-jour; they would learn just as much sitting outside (it was this high-school-esque forced attendance rather than this "I wish to learn" voluntary attendance.
Then came the stark realization; I'm better off listening to the lectures that are put out by the major universities. Even though I enjoy having forced times, these past few times I went to the lectures my mind wasn't thinking of math but of algorithms.
And then my thirst for knowledge would follow my work habits and be satiated when my mind is focused on the subject.
Since I don't care about grades.... why not?
Saturday, March 1, 2014
Codea, initial explorations of the iPad IDE
Codea, is, an IDE for the development of multimedia apps, specifically games. It comes complete with a few images ready for use and has a built in shader editor to prepare visual effects before use in game. There are some cute little demos, including a simple pixel-art image editor and rudimentary drum machine.
The API itself is often times made as simple as possible. Images are referred by their string names, and the API handles the loading part. You just draw with it! Touch information is stored in a global variable for easy polling. The game loop is already set up. And there are plenty of utility shape drawing functions.
The downside is that the API is too simple at times - I could overlook this if the app didn't claim to provide an environment enabling a person to make completely polished games for the App Store. The simple API is great for prototyping simple interactions.
Consider the simple task of a button. A button is ubiquitous, it should handle presses and provide appropriate feedback. Many of the more complex examples shipped with Codea use a button, yet each has its own abstraction. Spiritely, the pixel art tool, goes just as far as to try to replicate the native iOS feel. But that is difficult...
Let me explain, when a button is pressed, a typical UI will make it give user feedback. Like get darker, bevel in, etc. If the finger wanders off the button, but not off the touchscreen, then no other button should provide feedback. Imagine that where the finger goes down on a button, all events go back to that button. Such a feature requires planning, and above all simply reimplementing what's been already done a million times.
Yes, there are multiple interaction paradigms. The home screen on iOS uses the one described above.
In the end, if I were creating just the game scene on pong, then Codea would be perfect. If I wanted menus and more, then maybe I'd want something similar to a rudimentary GUI framework. Which I provide below.
One last note, the tabs are executed in order. So a super class should appear before any inheriting classes in the tabs.
In the end, I recommend Codea for prototyping on the go. Have an idea for something? Prototype quickly and show it to people right then and there. No need to lug a mac to fine tune interactions in a game prototype. It's kind of nice that way,
Below are a series of objects to use in Codea that may prove useful for UI work. It's in progress, but starting to make my development easier (I'm slowly progressing on it):
XControl = class()
function XControl:init(position, size)
self.position = position
self.size = size
self.parent = nil
self.children = {}
self.onDraw = {}
self.pvtxc = {}
end
function XControl:pvtDraw()
self:draw()
for i,v in ipairs(self.children)
do
pushMatrix()
translate(self.position.x, self.position.y)
v:pvtDraw()
for ind, drw in ipairs(self.onDraw)
do
drw(self)
end
popMatrix()
end
end
function XControl:addDrawFn(fn)
local l = #self.onDraw
self.onDraw[l] = fn
end
function XControl:draw()
end
function XControl:addChild(inChild)
inChild:removeFromParent()
local cid = #(self.children)+1
self.children[cid] = inChild
inChild.parent = self
inChild.pvtxc.childId = cid
end
function XControl:removeFromParent()
if self.parent == nil
then
return
end
local pcid = table.getn(self.parent.children)
if self.parent.pvtxc.count ~= 1 then
self.parent.children[self.pvtxc.childId]
= self.parent.children[pcid]
self.parent.children[self.pvtxc.childId].pvtxc.childId
= self.pvtxc.childId
end
table.remove(self.parent.children)
end
function XControl:pvtGetTouchedControl(pt)
for i,v in ipairs(self.children)
do
if v:isWorldPointWithin(pt)
then
return v:pvtGetTouchedControl(pt)
end
end
return self
end
function XControl:isPointWithin(pt)
return (pt.x >= 0 and pt.y >= 0
and pt.x <= self.size.x
and pt.y <= self.size.y)
end
function XControl:isWorldPointWithin(pt)
return self:isPointWithin(self:world2local(pt))
end
function XControl:isTouchWithin(touch)
return self:isWorldPointWithin(vec2(touch.x, touch.y))
end
function XControl:local2world(v2)
if self.parent == nil
then
return v2 + self.position
else
return self.parent:local2world(v2 + self.position)
end
end
function XControl:world2local(v2)
if self.parent == nil
then
return v2-self.position
else
return self.parent:local2world(v2 - self.position)
end
end
function XControl:pvtOnTouched(touch)
end
And for a button...
XButton = class(XControl)
function XButton:init(position, size)
XControl.init(self, position, size)
self.onPress = nil
self.onRelease = nil
self.onDrag = nil
self.onTouch = nil
end
function XButton:pvtOnTouched(touch)
if touch.state == BEGAN and self.onPress ~= nil
then
self.onPress(touch)
end
if touch.state == MOVING and self.onDrag ~= nil
then
self.onDrag(touch)
end
if touch.state == ENDED
then
if self.onRelease ~= nil
then
self.onRelease(touch)
end
if self:isTouchWithin(touch) and self.onTouch ~= nil
then
self.onTouch(touch)
end
end
end
Saturday, December 21, 2013
Solving Some Project Euler Problems in Haskell
Here are a few solutions to Project Euler problems done in Haskell. All of these were entered in gchi interactively. As much as possible I try to keep them as one-liners.
The ">" indicates the beginning of a line at the ghci command line.
Starting with problem 7, this ideal could not be kept since it was becoming unmanageable. With that problem I started to use modules. The maintenance of that module is documented below.
One final note; this post is an experiment at producing fewer posts but keeping them alive with data and updates rather than flood with posts. Quality over quantity seems to be my new mantra. A good long post completed over the course of a few months.
We desire a slightly more efficient way to enumerate primes. Note that no prime will be even since they are all divisible by 2. Also, primes become very sparse as we progress through the number line so discarding them quickly becomes kind of important. The first primes will be multiples of a number more often than the latter primes. Let us keep that in note and define a function to enumerate future primes:
Good! Let us suppose we had a way to perpetually enumerate future primes:
Sounds like it's time to rethink our algorithm. We know that division is expensive, so we should build a sieve. Sieve of Atkin (according to Wikipedia) is the modern-day best-case. In such a case, we wish to mark off numbers that we know to not be prime.
We can use Bertrand's Postulate and enumerate a set of values that we believe are prime between the intervals. I would rather point out the idea of diminishing returns and mention that '2' cuts out half the numbers from primality testing. '3' cuts out at most a quarter of the numbers. '5' less, '7' even less, etc. The problem is that we aren't testing just highly potential primes but the entire number line.
Let us try to enumerate all numbers that are multiples of the first few primes... And Eureka! A much better solution has emerged! Unfortunately, it does not have the runtime that I'd desire.
The idea is simple, build a list of known composite numbers and flip it to get anything that is prime. Yes - it is another implementation of the sieve of Eratosthenes. Where it excels is at reducing the number of divisions. There is a list being built that does not contain any prime. By comparing it with a list of all numbers, we get a list of potential primes. From that list, we can do simple primality tests.
Here is the code, in completion:
Just run the command "allPrimes' !! 10002" to get the answer. I counted 1 as a prime.
The ">" indicates the beginning of a line at the ghci command line.
Starting with problem 7, this ideal could not be kept since it was becoming unmanageable. With that problem I started to use modules. The maintenance of that module is documented below.
One final note; this post is an experiment at producing fewer posts but keeping them alive with data and updates rather than flood with posts. Quality over quantity seems to be my new mantra. A good long post completed over the course of a few months.
Problem 1:
This problem was relatively straight-forward. It's actually a nice one-liner!
> sum $ filter (\x -> x `mod` 3 == 0 || x `mod` 5 == 0) [1..999]
Problem 2:
First, create a fibonacci sequence list. Make sure it is tail recursive for performance - hence why the first two elements are not included in the recursive list. The filter and takeWhile should be interchangeable.
> let fib x y = (x+y):(fib y (x+y))> sum $ filter (\x -> x `mod` 2 == 0) $ takeWhile (<= 4000000) ([1,2] ++ fib 1 2)
Problem 3:
A much more interesting problem. Note, the maximum value of your prime number will be the square root of the target number.
You do not need to enumerate all primes. Actually, this would be slower as the sieve would take more time filtering numbers. To crack the number, we first find all integers that divide it. Then, of those integers, to determine which are prime, we see which divide each other.
To see why this works, consider an integer and all the integers that divide it. If an integer were not prime, it could be decomposed into prime numbers. Those prime numbers also divide the original number.
First identifying the dividing the integers being faster is only tractable for relatively small numbers.
"divs" finds all the integers that divide the given value.
"noDivs" is true if there is a value larger than "x" in "xs" which is divisible by "x".
"divs'" combines the previous two functions to find all the primes for the given value.
> let noDivs x xs = (length $ filter (\y -> (x `mod` y == 0) && (x > y)) xs) == 0> let divs x = filter (\y -> x `mod` y == 0) [2..(ceiling $ sqrt $ fromIntegral x)]> let divs' x = filter (\y -> noDivs y z) z where z = divs xmaximum $ divs' 600851475143
Problem 4:
Rather simple problem which can be solved in a single line. Simply import Data.List:
> filter (\x -> reverse x == x) $ map show $ reverse $ sort $ concat $ map (\x -> map (*x) [1..x] ) [1..999]
Problem 5:
So, let's start with the wrong solution. We could brute-force the problem as so:
> head $ filter snd $ map (\x -> (x,foldl (&&) True $ map (==0) $ map (\y -> x `mod` y) [2..20])) [100..]
We need a better solution. Let's suppose we knew the prime factors of the numbers that we're dealing with. Like so:
> let primesUntil p = filter (\x -> length (filter (\y -> x `mod` y == 0) $ [2..x-1]) == 0 ) [2..p]
Now, we can think of the solution as a permutation of the primes that arise from numbers 0...20. Then, let us suppose we also had a function to enumerate all the possible permutations:
> let combos v n c = zipWith (\x y -> x + ((v `div` y) `mod` c)) (replicate n 1) $ map (\x -> c^x) [0..n-1]> let primeCombos p = take (3^(length z)) $ map (\x -> foldl (*) 1 $ zipWith (*) (combos x (length z) 3) z)[0..] where z = (primesUntil p)
Finally, we can combine everything together to get:
> minimum $ map fst $ filter snd $ map (\x -> (x,foldl (&&) True $ map (==0) $ map (\y -> x `mod` y) [2..20])) $ primeCombos 20
Not ideal as a solution though. It takes quite a bit of time to run. What would be ideal? Proper analysis of the problems in terms of primes. The smallest product is a product of the primes of 0...20. Isolating the primes is a problem that would have added excess code though.
Problem 6:
Something that Haskell excels at, thankfully due to built-in big number support:
> let diffSq x = (foldl (+) 0 x)^2 - (foldl (\z y -> z + y*y) 0 x)> diffSq [1..100]
Problem 7:
For this problem, we will need a very fast function to calculate primes. Very fast. The naive solution though would be (assuming we have primesUntil from above):
> primesUntil 1000000000 !! 10000
Notice how the function doesn't return. primesUntil breaks down when we wish to compute large primes since we test against all previous numbers and not just known primes. A good prime function will use previous primes to find new primes. It will also discard even numbers from the start.
Let me cook up a few little functions to help...
isDividedBy is the first. It checks to see if any value divides any other value in a list. It is intended to be written as: "10 isDividedBy [3, 4, 7]". Note that foldr is more apt to lazy evaluation, which is exactly what we seek.
Let me cook up a few little functions to help...
isDividedBy is the first. It checks to see if any value divides any other value in a list. It is intended to be written as: "10 isDividedBy [3, 4, 7]". Note that foldr is more apt to lazy evaluation, which is exactly what we seek.
isDividedBy :: Integer -> [Integer] -> Bool
isDividedBy x xs = foldr (\a b -> (x `mod` a == 0) || b) False xs
We desire a slightly more efficient way to enumerate primes. Note that no prime will be even since they are all divisible by 2. Also, primes become very sparse as we progress through the number line so discarding them quickly becomes kind of important. The first primes will be multiples of a number more often than the latter primes. Let us keep that in note and define a function to enumerate future primes:
nextPrime :: Integer -> [Integer] -> Integer
nextPrime n xs = if (n `isDividedBy` xs)
then (nextPrime (n+2) xs)
else n
nextPrimes :: Integer -> [Integer] -> [Integer]Problem? Still doesn't perform as well as needed. How can we speed this code up? There are primality tests which we can apply to filter numbers rather rapidly. However, even with Fermat's Primality Test, we do not get much speed.
nextPrimes x xs = np:(nextPrimes (x+2) pl)
where np = nextPrime x xs
pl = xs ++ [np]
quickFermat :: Integer -> Bool
quickFermat p = a^(p-1) `mod` p == 1 where a = 2 -- p `div` 2
nextPrime :: Integer -> [Integer] -> Integer
nextPrime n xs = if ((quickFermat n) || (n `isDividedBy` xs))
then (nextPrime (n+2) xs)
else n
Sounds like it's time to rethink our algorithm. We know that division is expensive, so we should build a sieve. Sieve of Atkin (according to Wikipedia) is the modern-day best-case. In such a case, we wish to mark off numbers that we know to not be prime.
We can use Bertrand's Postulate and enumerate a set of values that we believe are prime between the intervals. I would rather point out the idea of diminishing returns and mention that '2' cuts out half the numbers from primality testing. '3' cuts out at most a quarter of the numbers. '5' less, '7' even less, etc. The problem is that we aren't testing just highly potential primes but the entire number line.
Let us try to enumerate all numbers that are multiples of the first few primes... And Eureka! A much better solution has emerged! Unfortunately, it does not have the runtime that I'd desire.
The idea is simple, build a list of known composite numbers and flip it to get anything that is prime. Yes - it is another implementation of the sieve of Eratosthenes. Where it excels is at reducing the number of divisions. There is a list being built that does not contain any prime. By comparing it with a list of all numbers, we get a list of potential primes. From that list, we can do simple primality tests.
Here is the code, in completion:
import Data.List
knownComposites :: Integer -> Integer -> Integer -> [Integer]
knownComposites p s m = if ( m > 0 ) then p:(knownComposites (p+s) s (m-s))
else []
mergeLists :: [Integer] -> [Integer] -> [Integer]
mergeLists [] [] = []
mergeLists [] b = b
mergeLists a [] = a
mergeLists (a:aa) (b:bb)= if (a == b) then a:(mergeLists aa bb)
else if (a<b) then a:(mergeLists aa (b:bb))
else b:(mergeLists (a:aa) bb)
mergeComposites :: [Integer] -> Integer -> [Integer]
mergeComposites [] _ = []
mergeComposites (p:pp)m = mergeLists (knownComposites p p m) (mergeComposites pp m)
compositesForPrimes :: [Integer] -> [Integer]
compositesForPrimes p = mergeComposites p (foldr (*) 1 p)
missingFrom :: [Integer] -> [Integer] -> [Integer]
missingFrom [] _ = []
missingFrom (a:aa) (b:bb) = if (a > b) then b:(missingFrom (a:aa) bb)
else missingFrom aa bb
potentialPrimes :: [Integer] -> [Integer]
potentialPrimes p = missingFrom (compositesForPrimes p) [2..]
quickFermat :: Integer -> Bool
quickFermat p = a^(p-1) `mod` p == 1 where a = 2 -- p `div` 2
isDividedBy :: Integer -> [Integer] -> Bool
isDividedBy _ [] = False
isDividedBy x xs = foldr (\a b -> (x `mod` a == 0) || b) False xs
nextPrime :: Integer -> [Integer] -> Integer
nextPrime n xs = if ((quickFermat n) || (n `isDividedBy` xs))
then (nextPrime (n+2) xs)
else n
nextPrimes :: Integer -> [Integer] -> [Integer]
nextPrimes x xs = np:(nextPrimes (x+2) pl)
where np = nextPrime x xs
pl = xs ++ [np]
allPrimes :: [Integer]
allPrimes = 1:2:3:5:(nextPrimes 5 [2,3,5])
primeFilter' :: [Integer] -> [Integer] -> [Integer]
primeFilter' p (m:mm) = if (m `isDividedBy` p)
then primeFilter' p mm
else m:(primeFilter' (p ++ [m]) mm)
allPrimes' = (1:ip) ++ (primeFilter' [] $ potentialPrimes ip)
where ip = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233]
Just run the command "allPrimes' !! 10002" to get the answer. I counted 1 as a prime.
Problem 8:
This one is a cute problem. We'll solve it by first defining a variable called number by manually concatenating the given number together onto one line:
> let number = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
Good! Good! Now, let us split up this string into groups of 5 digits!
fives :: [x] -> [[x]]
fives v = if ((length v) < 5) then ([])
else ((take 5 v):(fives $ drop 1 v))
Wonderful! Just one last part...
> import Data.Char
> maximum $ map (\x -> foldr (*) 1 $ map digitToInt x) $ fives number
What am I doing? Taking the big string called "number" and splitting it into substrings of "5" in length (look at the definition of fives). Then I'm mapping this lambda to each of the strings that multiplies the digits of the number together.
The "map digitToInt" will convert a string of character digits to a list of numbers. "234" becomes [2,3,4]. The foldr multiplies it all together. This is encapsulated in a map which applies the operation to the list from the fives function.
Finally, maximum gives us our solution.
Problem 9:
Finally! Another one-liner!
> map (\(x,y) -> x*y*(1000-x-y)) $ filter (\(x,y) -> x*x + y*y == (1000-x-y)*(1000-x-y) ) [(i,j) | i <- [1..1000], j <- [1..1000-i]]
There! Now read it backwards! We generate a tuple of numbers. The last one must be chosen so that the sum is 1000. Filter out any value that does not match the pythagorean inequality, and then map the remaining values to the product. And voila! Done!
Problem 10:
Ah! Another problem involving prime numbers! And we must enumerate an even greater set of primes than before! As a hint, we wish to be able to write something as such into ghci and get a result:
> foldr (+) (-1) $ takeWhile (<2000000) allPrimes'
Until next time...
Problem 11:
(To do)
Problem 12:
First, let us define a function that computes the triangle 'n':
Prelude> let triangle x = if x > 0 then x + triangle (x - 1) else 0
Second, we wish to get a list of all triangles:
Prelude> let triangles x = (triangle x):(triangles (x + 1))
Good, with this list of triangles, we need to get all the factors. The following returns 1 if divisible:
Prelude> let factors x y = if (y `mod` x == 0) then 1 else 0
Now
Problem n:
To be written.
Monday, December 2, 2013
Initial thoughts on video games and Wittgenstein
Overview
Indulging in both Wittgenstein's Tractatus and the new Legend of Zelda game have led to some mishmash of wires in my brain. Foremost, the Tractatus, the more I read it, seems to describe a game engine of sorts and the limits it imposes upon the imagination.Since this post is slightly longer than my regular posts, I have broken it down into a few sections.
- First: we will look at the mappings, how concepts from the Tractatus map flawlessly to the Legend of Zelda: a Link Between Worlds.
- Second: I shall muse on how it describes the world.
- Third: we shall consider what this means if we were an NPC (Non-Playable Character - an character inhabiting the digital world).
For convenience, I have highlighted any terms used by Wittgenstein in italics.
A little caveat - this writing is doubly to help me further my understanding of what I read by explaining my thoughts and as a reference for the future when I look upon the text again.
Mappings
Mappings are very relevant in the Zelda games. Recall that the behaviours of objects are encoded within themselves. Interestingly, the behaviour for interacting with a bomb is not encoded within a rock. I've tried blowing up a rock repeatedly to no avail. Recall that a rock can only be picked up and thrown. There is no way to blow up a rock (except for a special type of rock with a crack in it). Use a ton of dynamite and it will always remain.A state of affairs is essentially the layout within a dungeon. A level if you will. Using an appropriate editor, many state of affairs can be brought to life. All state of affairs are possible if imagined from objects. It is the objects of the game world that limit the imagination. Instead of composing complexes from atoms, the smallest building block is the size of a rock.
A picture is a design for a level. It can relate an actual level, but doesn't have to. It can be a subset of a level, a screen capture. We can think of a level.
A picture, in this sense can also be thought of. The thought encapsulates this toy world.
Game World
Interestingly, the thought process is further confined as we map the terms of the Tractatus to the toy world of a game.These first few pages that build a model of the world so aptly describe the limits of our digital worlds.
I'm still working out the details of how they mesh - but there is something there. Something describing the limits of what we can make, not just what we can think.
NPCs
There is also something interesting in regards to our own world. Consider the rabbit that takes over Link's house and sets up shop - to sell all his possessions for a healthy profit to Link. We obviously know that this character is following a simple script, but let us give him the benefit of the doubt and assign consciousness to this character.Let's suppose one day he decides to question how his world works. He would be able to analyze what is thinkable as Wittgenstein has done, eerily similar conclusions. Except, the micro world would be completely different.
To feel the world around him would be to see himself from above, hear things. He would see that he is made of pixels. But that would be normal. (I could have gone the route of seeing himself as a polygonal shape - conclusions would be similar). As long as pixels looked right without any magnification, everything would be ok.
But let's say our NPC is a scientist and decides to zoom in. Then what would be seen between the pixels?
Let's say we're dealing with an image encoded with the DCT (Discrete Cosine Transform). Zoom in a lot! As much as you wish! Underneath there is a wave-like function that provides progressively blurrier visuals. There is a point where the image is in focus.
I have deviated a bit, but this question has been in the back of my mind lately. Is there an ideal zoom for our world, and any further magnification reveals the algorithm and not the substrate? If I think of atoms as pixels (gross simplification, but hear me out), then as we zoom into atoms we are looking at a byproduct of the matter that holds the universe and not the actual matter.
Furthermore, are we at the intended zoom level, or are we just a happy accident that makes up the most basic of objects.
Wittgenstein must be rolling in his grave by now, by how I'm trying to subvert his work to apply to everyday toys.
Subscribe to:
Posts (Atom)