Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Для любителей головоломок, вот такое очень крутое задание в виде квеста от ребят, даже если не ищешь работу интересно.
zoon.ru/job.php
$p+1 не превосходит 127, то разницы не должно быть. С большими значениями уже хуже: в JS везде и всюду юникод, а в php… он отдельно поставляется.Пара слов о задании. Мне было все равно на чём человек его реализует, но сразу же обговаривались два условия:
я смогу его запустить,
Несколько раз у меня возникли трудности с запуском приложения:
Использовались какие-то библиотеки, которые не понятно где быстро взять.
Нужно было ставить IDE, SDK и всё на свете, чтобы лишь скомпилировать апп.
У меня были явно не все файлы проекта, а с незнакомым языком возиться его настраивать было не много желания.
<ssd.meister> Когда я сказал студентам принести лабу по алгоритмизации на любом языке программирования, я не подозревал, что на потоке найдётся мудак, который напишет её на… BRAINFUCK'е!
Почему Вы решили, что brainfuck студент использовал с целью постебаться над преподом. А если нет? Если он им активно увлекается (а это, как известно, хорошая разминка для мозгов) и поэтому его выбрал?

Мой вывод от общения с Вами (исходя из данной статьи) был бы а-ля «э, да такой всю душу вынет из сотрудника, пойду-ка ещё поищу»…
Ваш подход так же наводит на некоторые выводы. Нечёткая постановка ТЗ + последующая критика по мелочам.
Где вы видели 100% чёткую постановку ТЗ?
Мне было все равно на чём человек его реализует...
я смогу понять код
def current_user
store_location
false
end
Эффект должен работать при любых значениях M, N, V.
слева на право со скоростью V пробегает волна
var startPosition:uint
function frameHandler(e:Event):void {
for (var j:uint = 1; j < Height-1; j++) {
buffer.setPixel(startPosition, j, Math.max(bmp.getPixel(startPosition, j), bmp.getPixel(startPosition-1, j), bmp.getPixel(startPosition, j-1), bmp.getPixel(startPosition, j+1)));
}
startPosition = (startPosition -1) % Width;
bmp.copyPixels(buffer, buffer.rect, zeroPoint);
var rect:Rectangle = new Rectangle(0, 0, Size, Size);
for (i = 0; i < Width; i++) {
for (j = 0; j < Height; j++) {
rect.x = i*Size;
rect.y = j*Size;
display.fillRect(rect, colors[bmp.getPixel((i-startPosition)%Width,j)]);
}
}
}игр и 3d веб сайтов

Так и тут — задание сводится не к выполнению, а к угадыванию, чего хочет автор от кандидата.

Интересной была одна особенность всех решений — все… абсолютно все смотрели на задачу, следуя буква к букве её описанию в начале поста: сетка, по ней пробегает волна…


По умолчанию, если ничего не сказано, надо делать максимальное простое и понятное решение. Если оно без ООП простое и понятное, значит ок. Если без ООП получается запутанное, а с ООП простое, значит надо было использовать ООП.
Это не типичнейшая проблема заданий. Если в задании сказано «посчитать 2*2», не надо додумывать за автора условия и абстрагироваться, до x*y, до считывания примеров из файлов, до создания грамматик и т.д. Расширять можно бесконечно. Самое простое решение — print 2*2. Всё, что сверху — это overengineering.
мы получим классический антипаттерн GOD object.
var bmp:BitmapData = new BitmapData(Width, Height, false, 0x000000);
var buffer:BitmapData = new BitmapData(Width, Height, false, 0x000000);
var display:BitmapData = new BitmapData(Width*Size, Height*Size, false);
import flash.geom.Point;
import flash.display.BitmapData;
import flash.display.Bitmap;
const START_POINT:Point = new Point(1, 0);
const CELL_SIZE:int = 10;
const START_COLOR:int = 0xFFFFFF;
var imageWidth:int = stage.stageWidth / CELL_SIZE;
var imageHeight:int = stage.stageHeight / CELL_SIZE;
var bitmapData:BitmapData = new BitmapData(imageWidth, imageHeight, false);
var colors:Object = {};
var colorIndex:int;
addColor(START_COLOR);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.scaleX = bitmap.scaleY = CELL_SIZE;
addChild(bitmap);
stage.addEventListener(MouseEvent.CLICK, onStageClick);
stage.addEventListener(Event.ENTER_FRAME, onStageEnterFrame);
function addColor(color:int):void {
colorIndex++;
colors[color] = colorIndex;
}
function onStageClick(e:MouseEvent):void {
var position:int = e.localY / CELL_SIZE;
var color:int = Math.random() * 0xFFFFFF;
addColor(color);
bitmapData.setPixel(0, position, color);
}
function onStageEnterFrame(e:Event):void {
bitmapData.lock();
bitmapData.copyPixels(bitmapData, bitmapData.rect, START_POINT);
for (var i:int = 0; i < imageHeight; i++) {
var topPixel:int = (i == 0) ? START_COLOR : bitmapData.getPixel(1, i - 1);
var centerPixel:int = bitmapData.getPixel(1, i);
var bottomPixel:int = (i == imageHeight - 1) ? START_COLOR : bitmapData.getPixel(1, i + 1);
var topPixelIndex = colors[topPixel];
var centerPixelIndex = colors[centerPixel];
var bottomPixelIndex = colors[bottomPixel];
var pixelColor:int;
if (topPixelIndex >= centerPixelIndex && topPixelIndex >= bottomPixelIndex) pixelColor = topPixel;
else if (centerPixelIndex >= topPixelIndex && centerPixelIndex >= bottomPixelIndex) pixelColor = centerPixel;
else pixelColor = bottomPixel;
bitmapData.setPixel(0, i, pixelColor);
}
bitmapData.unlock();
}
if (topPixelIndex >= centerPixelIndex && topPixelIndex >= bottomPixelIndex) pixelColor = topPixel; else if (centerPixelIndex >= topPixelIndex && centerPixelIndex >= bottomPixelIndex) pixelColor = centerPixel; else pixelColor = bottomPixel;
function getPixelColor(...arguments):int
{
var maxIndex:int;
var result:int;
var length:int = arguments.length;
for (var i:int = 0; i < length; i++)
{
var color:int = arguments[i];
var colorIndex:int = colors[color];
if (maxIndex < colorIndex)
{
maxIndex = colorIndex;
rusult = color;
}
}
return result;
}
var topPixel:int = (i == 0) ? START_COLOR : bitmapData.getPixel(1, i - 1);
var centerPixel:int = bitmapData.getPixel(1, i);
var bottomPixel:int = (i == imageHeight - 1) ? START_COLOR : bitmapData.getPixel(1, i + 1);
var pixelColor:int = getPixelColor(topPixel, centerPixel, bottomPixel);
bitmapData.setPixel(0, i, pixelColor);
var maxIndex:int = Math.max(topPixelIndex, centerPixelIndex, bottomPixelIndex);
if (maxIndex == topPixelIndex) pixelColor = topPixel;
else if (maxIndex == centerPixelIndex) pixelColor = centerPixelIndex;
else pixelColor = bottomPixel;
import flash.geom.Point;
import flash.display.BitmapData;
import flash.display.Bitmap;
const START_POINT:Point = new Point(1, 0);
const CELL_SIZE:int = 10;
const START_COLOR:int = 0xFFFFFF;
var imageWidth:int = stage.stageWidth / CELL_SIZE;
var imageHeight:int = stage.stageHeight / CELL_SIZE;
var bitmapData:BitmapData = new BitmapData(imageWidth, imageHeight, false, START_COLOR:int);
var indexes:Object = {};
var colors:Array = [];
// Лучше использовать Vector вместо Array, но парсер кода Habrahabr из-за этого ломает всё подсветку синтаксиса.
// var colors:Vector.<int> = new Vector.<int>();
var colorIndex:int;
addColor(START_COLOR);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmap.scaleX = bitmap.scaleY = CELL_SIZE;
addChild(bitmap);
stage.addEventListener(MouseEvent.CLICK, onStageClick);
stage.addEventListener(Event.ENTER_FRAME, onStageEnterFrame);
function addColor(color:int):void {
indexes[color] = colorIndex;
colors[colorIndex] = color;
colorIndex++;
}
function onStageClick(e:MouseEvent):void {
var position:int = e.localY / CELL_SIZE;
var color:int = Math.random() * 0xFFFFFF;
addColor(color);
bitmapData.setPixel(0, position, color);
}
function onStageEnterFrame(e:Event):void {
bitmapData.lock();
bitmapData.copyPixels(bitmapData, bitmapData.rect, START_POINT);
for (var i:int = 0; i < imageHeight; i++) {
var topPixel:int = (i == 0) ? START_COLOR : bitmapData.getPixel(1, i - 1);
var centerPixel:int = bitmapData.getPixel(1, i);
var bottomPixel:int = (i == imageHeight - 1) ? START_COLOR : bitmapData.getPixel(1, i + 1);
var topPixelIndex = indexes[topPixel];
var centerPixelIndex = indexes[centerPixel];
var bottomPixelIndex = indexes[bottomPixel];
var maxIndex:int = Math.max(topPixelIndex, centerPixelIndex, bottomPixelIndex);
var pixelColor:int = colors[maxIndex];
bitmapData.setPixel(0, i, pixelColor);
}
bitmapData.unlock();
}
Многие сразу же сообразили, что в алгоритме движения наложенных друг на друга волн слева направо можно сильно оптимизировать отрисовку. Но, как не печально, многие этим вырыли себе могилу, запутавшись в своём же собственном коде
История была бы неполной, если бы я не приложил здесь канонически правильного решения.
На самом деле, изначально его не было. Лишь к концу второго десятка «проверенных работ» я стал задумываться, а как бы я решил эту задачу…
O(height * waves), зачем сюда вплетать ширину области прорисовки?class CanvasModel:
def __init__(self, width, height):
self.width, self.height = width, height
self.waves, self.current_wave = [], 0
self.matrix = [x[:] for x in [[0] * width] * height]
def add_wave(self, line):
self.current_wave += 1
self.waves.append([self.current_wave, line, 0])
self.matrix[line][0] = self.current_wave
def process_wave(self, wave):
[id, x, y], changed = wave, False
wave[2] += 1 # move the wave feather right
diag1 = [p for p in zip(range(x, -1, -1), range(y, -1, -1)) if p[1] < self.width]
diag2 = [p for p in zip(range(x+1, self.height), range(y-1, -1, -1)) if p[1] < self.width]
for row, col in diag1: # process the top diagonal
if id < self.matrix[row][col]: break # stop in case of colliding with another wave
self.matrix[row][col] = id # propagate the wave index through the diagonal
changed = True
for row, col in diag2: # process the bottom diagonal
if id < self.matrix[row][col]: break
self.matrix[row][col] = id
changed = True
return changed
def propagate(self):
self.waves = [wave for wave in self.waves if self.process_wave(wave)]
import curses
import time
import threading
def main(screen):
colors = ['BLACK', 'BLUE', 'CYAN', 'GREEN', 'MAGENTA', 'RED', 'WHITE', 'YELLOW']
curses.mousemask(curses.BUTTON1_PRESSED)
[curses.init_pair(i + 1, 0, getattr(curses, 'COLOR_' + color)) for i, color in enumerate(colors)]
canvas = CanvasModel(80, screen.getmaxyx()[0] - 1)
threadLock = threading.Lock()
def update_time(screen):
while True:
canvas.propagate()
screen.clear()
threadLock.acquire()
for line in canvas.matrix:
for elem in line:
screen.addstr(" ", curses.color_pair(elem % len(colors) + 1))
screen.addstr("\n")
screen.refresh()
threadLock.release()
time.sleep(.02)
clock = threading.Thread(target=update_time, args=(screen,))
clock.daemon = True
clock.start()
while True:
event = screen.getch()
if event == curses.KEY_MOUSE:
line = curses.getmouse()[2]
if line < canvas.height:
threadLock.acquire()
canvas.add_wave(line)
threadLock.release()
else:
break
curses.endwin()
if __name__ == "__main__":
curses.wrapper(main)
На экране есть сетка M на N из цветных квадратиков. Нужно реализовать на этой сетке следующий эффект — по клику слева направо со скоростью V пробегает волна, меняя цвет квадратиков на другой (единый для всей волны). Эффект должен работать при любых значениях M, N, V. Волна начинается всегда у левой стенки. Одновременно может идти несколько волн разного цвета.
Что можно узнать о кандидате по тестовому заданию