Remove images from PDF - image

I read Create a tiff with only text and no images from a postscript file with ghostscript and try to use KenS`s answer.
But this method remove only "black" images - image contain data only in black channel (PDF has colorspace CMYK). How can i remove all images in my case?

This does a better job, but its incomplete. It doesn't deal with images using multiple data sources for example. Its essentially untested, except that I did test your smaller file (pages.pdf) by using ps2write to convert to PostScript and then the PostScript program below, and teh pdfwrite device, to convert back to PDF.
One of the first things you will notice is that almost all the text has vanished from your document. That's because the fonts you are using are bitmap fonts, and the program can't tell the difference between a bitmap representing a character, and any other kind of bitmap. For this file you can solve that by removing the definition of imagemask because all the characters use imagemask, and the other images use 'image'.
I have a sneaky suspicion the formatting of the program is going to get messed up here :-(
8<------------------------------8<--------------------------8<-------------------------
%!
%
% numbytes -file- ConsumeFileData -
%
/ConsumeFileData {
userdict begin
/DataString 256 string def
/DataFile exch def
/BytesToRead exch def
%(BytesToRead = ) print BytesToRead ==
mark
{
DataFile DataString readstring { % read bytes
/BytesToRead BytesToRead 256 sub def % not EOF subtract 256 from required amount.
%(Read 256 bytes) ==
%(BytesToRead now = ) print BytesToRead ==
} {
length
%(Read ) print dup 256 string cvs print (bytes) ==
BytesToRead exch sub /BytesToRead exch def % Reached EOF, subtract length read froom required amount
%(BytesToRead now = ) print BytesToRead ==
exit % and exit loop
} ifelse
} loop
%BytesToRead ==
BytesToRead 0 gt {
(Ran out of image data reading from DataSource\n) ==
} if
cleartomark
end
} bind def
%
% numbytes -proc- ConsumeProcData -
%
/ConsumeProcData {
userdict begin
/DataProc exch def
/BytesToRead exch def
{
DataProc exec % returns a string
length BytesToRead exch sub % subtract # bytes read
/BytesToRead exch def
BytesToRead 0 le {
exit % exit when read enough
} if
} loop
end
} bind def
/image {
(image) ==
dup type /dicttype eq {
dup /MultipleDataSources known {
dup /MultipleDataSources get {
(Can't handle image with multiple sources!) ==
} if
} if
dup /Width get % stack = -dict- width
exch dup /BitsPerComponent get % stack = width -dict- bpc
exch dup /Decode get % stack = width bpc -dict- decode
length 2 div % decode = 2 * num components
exch 4 1 roll % stack = -dict- width bpc ncomps
mul mul % stack = -dict- width*bpc*ncomps
7 add cvi 8 idiv % stack = -dict- width(bytes)
exch dup /Height get % stack = width -dict- height
exch /DataSource get % stack = width height DataSource
3 1 roll % stack = DataSource width height
mul % stack = DataSource widht*height
exch % stack = size DataSource
} {
5 -1 roll
pop % throw away matrix
mul mul % bits/sample*width*height
7 add cvi 8 idiv % size in bytes of data floor(bits+7 / 8)
exch % stack = size DataSource
} ifelse
dup type /filetype eq {
ConsumeFileData
} {
dup type /arraytype eq or
1 index type /packedarraytype eq or {
ConsumeProcData
} {
pop pop % Remove DataSource and size
} ifelse
} ifelse
} bind def
/imagemask {
(imagemask)==
dup type /dicttype eq {
dup /MultipleDataSources known {
dup /MultipleDataSources get {
(Can't handle imagemask with multiple sources!) ==
} if
} if
dup /Width get % stack = -dict- width
7 add cvi 8 idiv % size in bytes of width floor(bits+7 / 8)
exch dup /Height get % stack = width -dict- height
exch /DataSource get % stack = width height DataSource
3 1 roll % stack = DataSource width height
mul % stack = DataSource width*height
exch % stack = size DataSource
} {
5 -1 roll
pop % throw away matrix
mul mul % bits/sample*width*height
7 add cvi 8 idiv % size in bytes of data floor(bits+7 / 8)
exch % stack = size DataSource
} ifelse
dup type /filetype eq {
ConsumeFileData
} {
dup type /arraytype eq or
1 index type /packedarraytype eq or {
ConsumeProcData
} {
pop pop % Remove DataSource and size
} ifelse
} ifelse
} bind def
/colorimage {
(colorimage)==
dup 1 ne {
1 index
{
(Can't handle colorimage with multiple sources!) ==
} if
} {
exch pop % get rid of 'multi'
% stack: w h bpc m d ncomp
3 -1 roll pop % stack: w h bpc d ncomp
exch 5 -1 roll % stack d w h bpc ncomp
mul mul mul % stack: d w*h*bpc*ncomp
7 add cvi 8 idiv exch % stack: bytes datasource
} ifelse
dup type /filetype eq {
ConsumeFileData
} {
dup type /arraytype eq or
1 index type /packedarraytype eq or {
ConsumeProcData
} {
pop pop % Remove DataSource and size
} ifelse
} ifelse
} bind def

That technique should work for images in any colour, because the image operator is used for both colour and monochrome images. Unless your file uses the obselete level 1.5 'colorimage' operator. I can't recall if I redefined that operator in the example, if not then yuo can redefine it in a similar fashion.
In fact I see that I offered redefinitions for image, colorimage and imagemask, so all image types should be elided. Perhaps you could share an example ?

Related

Avoid dots in white spaces with custom halftone screensets

I am trying to set up custom angle/frequency halftone screensets with ghostscript and ran into a peculiar problem. The resulting output contains black dots where there should be none.
As a reproducer I found this code:
%!PS-Adobe-2.0
% Sample code to explore the different screen and spot functions
% Written by Bruce Barnett
% Inspired by Michael Thorne
% PostScript Language Journal Vol 1, Number 4
%
%
% define some abbreviations
/l /lineto load def
/m /moveto load def
/rl /rlineto load def
/rm /rmoveto load def
/sg /setgray load def
/sh /show load def
/slw /setlinewidth load def
/st /stroke load def
/tr /translate load def
% and some places to store some information
/str 300 string def % define a string
/ss 50 def % defines square size
/fountstring 256 string def
% print a fountain
/PrintFountain {
% create a string containing values from 0 to 255
0 1 255 {fountstring exch dup put } for
% scale a 1 by 1 image to the size that will spread across the page
% first number is the width, second the height
600 45 scale
% construct/transform the image
256 1 8 [256 0 0 1 0 0] {fountstring} image
} bind def
% Print a tinted box
/TintBox { %define a tinted box, size (ss by ss)
tint 100 div sg
newpath
0 0 m
ss 0 l
ss ss l
0 ss l
closepath fill
} def
/LabelBox { % define a procedure to label a box
10 ss 2 div m % move to (10, ss/2)
lettercolor sg % select color
tint 3 string cvs sh
(% grey) sh
} def
/NextLine {-1 ss mul 10 mul -1 ss mul tr} def % goto next line
/NextLoc {ss 0 tr} def % goto next location (or place for a square)
/PrintMatrix { % define a procedure to print a row of squares
% if at the end of the row, go to the next line
% else - go to the next location
/tint exch def
TintBox % draw the box
LabelBox % add the label
/count count 1 add def % increase the count by one
count 11 lt { % move to next spot
NextLoc
} {
NextLine /count 0 def
} ifelse
} def
% show details of layout (Halftone, etc.)
/ShowDetails {
/str 300 string def
100 750 m
(Spot Procedure Name= ) show
/SpotFunctionName load show % => freq angle
currentscreen % => freq angle proc
pop % ignore procedure
( Angle= ) show
str cvs show % => freq
( Frequency= ) show
str cvs show
} bind def
% A procedure to set the screen angle
% and remember the name of the function
% so we can print it
/ScreenSet { % set screen function
% ang freq /spot_function ScreenSet
dup str cvs /SpotFunctionName exch def
load setscreen
} bind def
/PrintPage {
% also remember time to print page
/time_start usertime def
ShowDetails % prints the halftone screen
gsave % save the graphic state
ss ss 10 mul tr
0 0 m
/count 0 def
/lettercolor 1 def % select white letters
0 1 10 {PrintMatrix} for
10 1 20 {PrintMatrix} for
20 1 30 {PrintMatrix} for
30 1 40 {PrintMatrix} for
40 1 50 {PrintMatrix} for
/lettercolor 0 def % change to black letters
50 1 60 {PrintMatrix} for
60 1 70 {PrintMatrix} for
70 1 80 {PrintMatrix} for
80 1 90 {PrintMatrix} for
90 1 100 {PrintMatrix} for
grestore %restore graphic state
gsave % save it again, for the fountain
PrintFountain
grestore % restore
0 sg
% now print the elapsed time
100 775 m (elapsed time (milliseconds) = ) show
usertime time_start sub str cvs show
showpage % print the page
} bind def
% Here are the different spot functions
% These are suggested by Adobe
/spot_round { % simple round
dup mul exch dup mul add 1 exch sub
} def
% Inverted Round
/spot_iround {
dup mul exch dup mul add 1 sub
} def
% Euclidean Composite
/spot_euclid { % default on many new PS printers
abs exch abs 2 copy add 1 gt {
1 sub dup mul exch 1 sub dup mul add 1 sub
} {
dup mul exch dup mul add 1 exch sub
} ifelse
} def
% Rhomboid
/spot_rhomboid { % Rhomboid
abs exch abs .8 mul add 2 div
} def
% Line
/spot_line {
exch pop abs 1 exch sub
} def
% Diamond
/spot_diamond {
abs exch abs 2 copy add .75 le
{
dup mul exch dup mul add 1 exch sub
} {
2 copy add 1.25 le {
.85 mul add 1 exch sub
} {
1 sub dup mul exch 1 sub dup mul add 1 sub
} ifelse
} ifelse
} def
% Inverted Elliptical
/spot_iellipt {
dup mul .9 mul exch dup mul add 1 sub
} def
/spot_rb { % another from the "Red Book"
180 mul cos exch 180 mul cos add 2 div
} def
/spot_line { % simple line
pop
} def
/spot_line2 { % simple line going the other way
exch pop
} def
% End of definitions, now to print
% Use 8 point Helvetica
8 /Helvetica-Bold findfont exch scalefont setfont
% each "PrintPage" prints one test page
% Print 5 test pages or different screens
% using the same spot function
53 45 /spot_euclid ScreenSet PrintPage
75 0 /spot_euclid ScreenSet PrintPage
83 56 /spot_euclid ScreenSet PrintPage
106 45 /spot_euclid ScreenSet PrintPage
150 0 /spot_euclid ScreenSet PrintPage
% Now print 10 other spot functions, same screen
53 45 /spot_round ScreenSet PrintPage
53 45 /spot_iround ScreenSet PrintPage
53 45 /spot_euclid ScreenSet PrintPage
53 45 /spot_rhomboid ScreenSet PrintPage
53 45 /spot_line ScreenSet PrintPage
53 45 /spot_diamond ScreenSet PrintPage
53 45 /spot_iellipt ScreenSet PrintPage
53 45 /spot_rb ScreenSet PrintPage
53 45 /spot_linea ScreenSet PrintPage
53 45 /spot_lineb ScreenSet PrintPage
% I think you get the idea.....
% end of file
with gs -r1440 -sOutputFile=test%d.tif -sDEVICE=tiffsep1 -f example1.gs I get in test5(black).tif (spot_euclid freq=150) following patterns in progression from white to (near) black:
Where are these dots coming from and how to avoid them? I noticed that the dots within the white are gone at 720 but I need 1440 for my application.
I already looked around and found people with similar problems but no solution. This comment assumes that the white is not clean but that does not explain why the non white parts contain those dots.
EDIT: Smaller reproducer
I noticed that this behavior is also reproducible with a smaller example and stock ghostscript spot function:
<< /PageSize [10 10] >> setpagedevice
0.75 0.5 0 0 setcmykcolor
newpath 0 0 moveto 10 0 lineto 10 10 lineto 0 10 lineto closepath fill
showpage
quit
Running this with gs -r300 -dDITHERPPI=20 -sOutputFile=test%d.tif -sDEVICE=tiffsep1 -f test.gs I get the following output tifs for CMYK channels:
Cyan:
Magenta:
Yellow:
Black:
And for 600 DPI I also get dots in the empty channels:
Cyan:
Magenta:
Yellow:
Black:
I used low dither PPI to make the problem more visible but even in default settings, the points are there.
As noted by #KenS this was a bug in ghostscript that has been resolved.

Why does arbitrary selection of next cell affect performance in backtracking Sudoku solver?

I've made a simple Sudoku class (in Python). Its main attributes are the following:
def __init__(self, it: iter = None):
self.grid = [[None for _ in range(9)] for _ in range(9)]
self.usedInRow = [[False for _ in range(10)] for _ in range(9)]
self.usedInCol = [[False for _ in range(10)] for _ in range(9)]
self.usedInBox = [[False for _ in range(10)] for _ in range(9)]
def writeCell(self, pos: tuple, val: int) -> bool: [...]
def eraseCell(self, pos: tuple): [...]
self.grid keeps track of the actual numbers in the Sudoku. self.usedInRow, self.usedInCol, and self.usedInBox are boolean arrays that keep track of which numbers have been used in each row/column/square. writeCell is a method that tries to write a number in an empty cell and returns whether it succeeded (according to the rules of Sudoku). Finally, eraseCell replaces a cell's content with None.
Inside the class I've written a recursive-backtracking solver method. When implementing the solver, I tried different approaches for selecting which cell to fill in next. The first thing I tried was simply starting from (0, 0) and incrementing the position left-to-right and top-to-bottom (with columns as the 'small' unit and rows as the 'big' unit).
But that's not general enough (if for some reason the solver started solving from a position other than (0, 0) every empty cell before that would be skipped). So I added a member to keep track of empty cells:
def __init__(self, it: iter = None):
[...]
self.emptyCells = [(i, j) for i in range(9) for j in range(9)]
I modified the writeCell and eraseCell methods to mantain the correct record. At this point the solver looks more or less like this:
def solve(self) -> bool:
[...]
def _solve() -> bool:
if not self.emptyCells: return True
pos = self.emptyCells[0]
for n in range(1, 10):
if self.writeCell(pos, n):
if _solve(): return True
self.eraseCell(pos)
else: return False
success = _solve()
[...]
return success
At this point I thought that maybe it would be better if the self.emptyCells member was a set instead of a list: I didn't want duplicates, didn't need indexed access (I thought that it wouldn't matter the order in which cells were filled in), and wanted fast deletion. So I modified the self.emptyCells attribute
self.emptyCells = set((i, j) for i in range(9) for j in range(9))
and the methods that referred to it (for example I used .discard() instead of .remove() in writeCell). The solver method now looked like this:
def solve(self) -> bool:
[...]
def _solve() -> bool:
if not self.emptyCells: return True
pos = self.emptyCells.pop() # Get arbitrary position
for n in range(1, 10):
if self.writeCell(pos, n):
if _solve(): return True
self.eraseCell(pos)
else:
self.emptyCells.add(pos) # Backtrack
return False
success = _solve()
[...]
return success
To my surprise, the second approach (using a set) took about one minute to solve an empty Sudoku, whilst the first approach (using a list) took about two seconds. Why is that? Does the arbitrarily chosen position conferred by set.pop() affect the efficiency of the algorithm, compared to filling cells in order?
Full code
Using a list
import queue
import threading
import colorama
colorama.init() # For ANSI escape codes
class Sudoku:
#staticmethod
def isSudoku(S: iter):
return len(S) == 9 \
and all(len(row) == 9 for row in S) \
and all(num in range(1, 10) for row in S for num in row)
def __init__(self, it: iter = None):
self.grid = [[None for _ in range(9)] for _ in range(9)]
self.usedInRow = [[False for _ in range(10)] for _ in range(9)]
self.usedInCol = [[False for _ in range(10)] for _ in range(9)]
self.usedInBox = [[False for _ in range(10)] for _ in range(9)]
self.emptyCells = [(i, j) for i in range(9) for j in range(9)]
if it is not None:
for i in range(9):
for j, num in zip(range(9), it):
if num is not None:
if not self.writeCell((i, j), num): raise ValueError("Invalid Sudoku")
def __iter__(self):
return iter(self.grid)
def __len__(self):
return 9
def __str__(self):
def numsToStr(row):
for num in row: yield num if num is not None else ' '
def rowsBlock(i):
yield ''
for row in self.grid[3 * i:3 * (i + 1)]:
yield '|{} {} {}|{} {} {}|{} {} {}|'.format(*numsToStr(row))
yield ''
def blocks():
yield ''
for i in range(3): yield '\n'.join(rowsBlock(i))
yield ''
return ('-' * 19).join(blocks())
def __getitem__(self, key: tuple):
if not len(key) == 2: raise TypeError("Two indices needed")
r, c = key
return self.grid[r][c]
def __setitem__(self, key: tuple, value: int):
if not len(key) == 2: raise TypeError("Two indices needed")
self.eraseCell(key)
self.writeCell(key, value)
def _canWrite(self, r: int, c: int, b: int, val: int) -> bool:
if self.usedInRow[r][val] or self.usedInCol[c][val] or self.usedInBox[b][val] \
or self.grid[r][c] is not None: return False
self.usedInRow[r][val] = self.usedInCol[c][val] = self.usedInBox[b][val] = True
return True
def writeCell(self, pos: tuple, val: int) -> bool:
if val is None: return True # Ignore writing none
r, c = pos
b = 3*(r//3) + c//3
if not self._canWrite(r, c, b, val): return False
# noinspection PyTypeChecker
self.grid[r][c] = val
self.emptyCells.remove(pos)
return True
def eraseCell(self, pos: tuple):
r, c = pos
b = 3*(r//3) + c//3
val = self.grid[r][c] # Get old value for reference
if val is None: return # If there wasn't anything in the first place
self.grid[r][c] = None # Actually erase
self.emptyCells.append(pos)
# noinspection PyTypeChecker
self.usedInRow[r][val] = self.usedInCol[c][val] = self.usedInBox[b][val] = False
def solve(self) -> bool:
printQueue = queue.PriorityQueue()
def printer():
while True:
priority, item = printQueue.get()
if item is StopAsyncIteration:
break
print(item)
print('\x1b[13A', end='')
printQueue.task_done()
printThread = threading.Thread(target=printer, name="PrintThread")
printThread.start()
def _solve() -> bool:
if not self.emptyCells: return True
pos = self.emptyCells[0]
for n in range(1, 10):
if self.writeCell(pos, n):
if _solve(): return True
printQueue.put((1, self))
self.eraseCell(pos)
else:
return False
success = _solve()
printQueue.put((0, StopAsyncIteration))
printThread.join()
return success
Using a set
The only things that change are the following.
_solve() internal method:
def _solve():
if not self.emptyCells: return True
pos = self.emptyCells.pop()
for n in range(1, 10):
if self.writeCell(pos, n):
if _solve(): return True
printQueue.put((1, self))
self.eraseCell(pos)
else:
self.emptyCells.add(pos)
return False
eraseCell and writeCell:
def writeCell(self, pos: tuple, val: int):
if val is None: return True # Ignore writing none
r, c = pos
b = 3*(r//3) + c//3
if not self._canWrite(r, c, b, val): return False
# noinspection PyTypeChecker
self.grid[r][c] = val
self.emptyCells.discard(pos)
return True
def eraseCell(self, pos: tuple):
r, c = pos
b = 3*(r//3) + c//3
val = self.grid[r][c] # Get old value for reference
if val is None: return # If there wasn't anything in the first place
self.grid[r][c] = None # Actually erase
self.emptyCells.add(pos)
# noinspection PyTypeChecker
self.usedInRow[r][val] = self.usedInCol[c][val] = self.usedInBox[b][val] = False
Note
The reason I don't put back pos in the list version—and also why I get pos as self.emptyCells[0] instead of self.emptyCells.pop(0)—is because writeCell and eraseCell already take care of that: if writeCell succeeds in writing a (previously empty) cell, then it will call self.emptyCells.remove(pos)—and here's another reason why I'm not popping the list: otherwise I would be removeing a non-existent element in the list, and would have to catch the ValueError.
After that, if backtracking occurs (i.e. the _solve() recursive call returns False), eraseCell will put pos back in the list. Thus, if the for loop "fails"—i.e., the else branch is entered—, the last eraseCell will already have put pos back.
On the other hand, when using a set, there is no way of accessing an element without removing it from the set (to my knowledge). Thus, I'm forced to pop from it and put it back in manually. That's why discard is used instead of remove in the set-version of writeCell, since pos may already have been popped by solve_.
An alternative maybe would be to save pos = self.emptyCells.pop() and add it straight back (self.emptyCells.add(pos)), and then proceed with solve_. Then I could change discard to remove.
Usage example
sudoku = Sudoku()
sudoku.solve()
print(sudoku)
Profiling results
I profiled both versions but didn't find any obvious culprit—that is, the proportions of cumulative time taken by each method were very similar, although the actual absolute time they took was just scaled up in the set version with respect to the list version.
Update — pos counts
I added an array to keep track of how many times each pos was selected to be explored, and I printed it at the end of the solve. Here are the results.
List version:
[[ 1 1 1 1 1 1 1 1 1]
[ 1 1 1 1 145 671 7169 9869 7606]
[ 774 1115 645 7 2066 1240 451 463 554]
[ 511 466 504 424 554 422 358 502 566]
[ 545 224 507 539 578 404 487 357 574]
[ 421 421 452 436 465 406 326 621 483]
[ 436 519 284 462 545 534 410 563 730]
[ 433 561 311 397 365 254 308 708 384]
[ 445 559 558 413 513 572 564 511 686]]
Set version (as far as I can tell, results are consistent):
[[ 19895 1 91239 66620 1 1 76794 1 1]
[ 1 1 77617 43061 95435 1 1 49617 77772]
[ 54441 1 1 96081 79660 1 1 1 89575]
[101233 1 1 85645 55172 1 1 1 54613]
[ 1 1 71512 61978 5531 1 76794 82692 74311]
[ 96268 1 57136 92052 1 1 86104 91911 1]
[ 1 98119 95706 10680 1 97232 67210 1 39094]
[ 53447 1 1 1 89846 1 1 88072 1]
[ 74468 19103 1 39934 75698 1 1 90778 53260]]

Random Number Generator - arc4Random - Numbers can not be same

I have a random number generator using arc4Random and integers with three numbers, number1, number2, number3, in the range 1 - 3. A zero is not permitted. That part I have sorted due to a previous request on here, however, when the test button is pressed, I want to ensure the random numbers are not the same, i.e. if number1 displays 2, then number2 and number3 can not display 2 etc.
I tried to do this longhand below, but there must be a simpler way of doing it.
How would this be written in code as I have only been learning Xcode for about 6 weeks?
Regards.
Del Hinds
#IBAction func testButtonPressed(sender: UIButton) {
var str = "Hello, playground"
var number1 = Int(arc4random() % UInt32(4))
if number1 == 0 {
number1 = 1
}
var number2 = Int(arc4random() % UInt32(4))
if number2 == 0 {
if number1 == 1 {
number2 = 2
}
else if number1 == 2 {
number2 = 3
}
else if number1 == 3 {
number2 = 1
}
number2 = 1
}
label2TextLabel.text = "\(number2)"
var number3 = Int(arc4random() % UInt32(4))
if number3 == 0 {
if number2 == 1 {
number3 = 2
}
else if number2 == 2 {
number3 = 3
}
else if number2 == 3 {
number3 = 1
}
number3 = 1
}
label3TextLabel.text = "\(number3)"
If you are using ios9's GameplayKit, consider GKShuffledDistribution.
Playground example:
import GameplayKit
let distribution = GKShuffledDistribution(lowestValue: 1, highestValue: 3)
for i in 1...36 { // Do 12 groups of 3
print(distribution.nextInt(), appendnewline: false)
if i % 3 == 0 { print(" ", appendnewline: false ) }
}
Sample result:
213 132 321 312 213 132 132 123 132 231 132 123
Or consider GKRandomSource:
import GameplayKit
blocks : [AnyObject] = ["A","B","C"]
for _ in 1...5 { // do 5 shuffles
blocks = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(blocks)
print(blocks)
}
Sample result:
[A, C, B]
[B, C, A]
[B, A, C]
[C, A, B]
[B, A, C]
Swift 3:
GKShuffledDistribution - No real change, modified print usage.
import GameplayKit
let distribution = GKShuffledDistribution(lowestValue: 1, highestValue: 3)
for i in 1...36 {
print(distribution.nextInt(), terminator: "")
if i % 3 == 0 { print(" ", terminator: "" ) }
}
GKRandomSource usage revision
Replaced AnyObject with Any
Now use arrayByShufflingObjects(in: blocks)
gives
import GameplayKit
blocks : [Any] = ["A","B","C"]
for _ in 1...5 { // do 5 shuffles
blocks = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: blocks)
print(blocks)
}
A crude way of doing this is to start with an array of the possible number set {1, 2, 3} in your case, and, swap random elements in the array a few times, using the built-in random generator.
If however you require the shuffling to have the statistical property that the probability of a given number occurring conditional on it having not already occurred is 1 / (numbers remaining), then adopt the more rigorous Fisher-Yates shuffle.
Create an array (or set) of assigned numbers. When assigning a new number, check to see if the number is already in the array. If it is then assign a new random number. Repeat.
Once a number is assigned, add it to the array. Check if the array size is greater than or equal to the range of permitted numbers. If the number of random numbers is exhausted then throw an error and don't allow more numbers to be randomly assigned.
If you're doing this for large sets of numbers, you should check to make sure the size of the array of used numbers is not larger than about half the size of the range of assignable numbers.
If you're doing this for a small set of numbers, then it would be better to add the numbers in the range to an array and remove them from the array as you assign them.

SpriteKit for loop

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.

Postscript layout from top to bottom

Hi I have a postscript file that layouts an image from left to right.
%%% Temporary
/Fix_long 4.2 cm def
/Fix_short 3.2 cm def
%%% Set Image Scale
/SetFixScale { 2 copy gt { Fix_long Fix_short }{ Fix_short Fix_long }ifelse scale } bind def
%%% Set put coordinate
/SetXAdjust { 2 copy gt
{ X_Step Fix_long sub 2 div floor }
{ Fix_long Fix_short sub 2 div} ifelse /XAdjust exch def
} bind def
/YAdjust 1.0 cm def
%%% Temporary
/Row 4 def
/Column 5 def
/X_Step urx llx sub Row div floor def
/Y_Step ury lly sub Column div floor def
/Row_pos 0 def
/Column_pos 1 def
/SetPutPosition {
llx X_Step Row_pos mul add
ury Y_Step Column_pos mul sub translate
DrawFrame
DrawFileName
XAdjust YAdjust translate
Row 1 sub Row_pos eq { /Row_pos 0 def /Column_pos Column_pos 1 add def }{ /Row_pos Row_pos 1 add def } ifelse
Column_pos Column gt { /Column_pos 1 def } if
} bind def
I tried changing the postscript to layout the images from top to bottom. I can layout the image from top to bottom but I can only put it on the first column.
/SetPutPosition {
llx X_Step Row_pos mul add
ury Y_Step Column_pos mul sub translate
DrawFrame
DrawFileName
XAdjust YAdjust translate
Row 1 sub Row_pos eq { /Row_pos 0 def /Column_pos Column_pos 1 add def }{ /Column_pos Column_pos 1 add def } ifelse
Column_pos Column gt { /Row_pos 1 def } if
} bind def
Not all the program is given, for example llx, lly, urx and ury are not defined. SO its impossible to reproduce what you are doing.....
The definition of rows and columns seems odd to me too, since rows increment in the x direction and columns decrement in the y direction.
I'd assume that the program operates in a loop (also not shown). On each iteration of the loop it sets the position on the page to:
x = llx + (X_Step * Row_pos)
y = ury - (Y_Step * Column_pos)
Then program then subtracts 1 from Row and compares with Row_pos. If they are the same then we reset the row, otherwise we add 1 to Row_pos. In effect we increment Row_pos until we get to Row - 1.
Now, if we reset the row, then we set Row_pos back to 0, and add 1 to column_pos.
Finally, we compare Column_pos and Column, if Column_pos is greater than Column, then we reset Column_pos to 1. Since we would have also reset Row_pos in the preceding control block, this is effectively a complete page reset, and starts again from the initial values.
Your code starts by checking Row_pos against Row again (when you should be checking Column_pos against Column). If Row_pos hasn't reached Row then you add 1 to Column_pos. Then you check Column_pos against Column and if its greater you reset Row_pos.
Notice that the only way you can alter Row_pos is if Row_pos is equal to Row - 1
If it is, then you reset Row_pos to 0. After that its impossible to increment Row_pos unless Row is 1.
Basically your logic is broken.
You want to compare Column_pos against Column - 1. When they are equal you want to set Column_pos to 1 and increment Row_pos, otherwise you want to increment Column_pos. Finally, if Row_pos is greater than Row, you want to reset Row_pos top 0.
So, bearing in mind thaqt I can't test this, because not all the code is present, something like :
/SetPutPosition {
llx X_Step Row_pos mul add
ury Y_Step Column_pos mul sub translate
DrawFrame
DrawFileName
XAdjust YAdjust translate
Column 1 sub Column_pos eq { /Column_pos 1 def /Row_pos Row_pos 1 add def }{ /Column_pos Column_pos 1 add def } ifelse
Row_pos Row gt { /Row_pos 0 def } if
} bind def

Resources