Cómo recuperarse de internet DDOS

17

El Internet ha fallado. Los ataques DDoS ahora son rampantes y generalizados. Depende de usted tomar el control y reparar Internet.

Cada bot controlará 20 nodos en esta red. Cada nodo es activo o seguro , tiene un propietario y tiene una fuerza, que comienza en 2. Cada nodo activo está conectado a todos los demás nodos activos.

Cada turno, recibirá una lista de todos los nodos activos con su fuerza. Para cada uno de los nodos activos que posee, usted:

  1. Designe un nodo activo al que desee transferir toda su fuerza, o
  2. Ahorra y aumenta su fuerza

Entonces sucede lo siguiente en orden :

  1. Un Nodo que elija guardar su fuerza aumentará su fuerza en 1.
  2. Todos los nodos que eligen transferir su fuerza transferirán simultáneamente toda su fuerza al nuevo nodo.
  3. Si a un nodo se le transfirió la fuerza de un nodo enemigo, se producirá un ataque. Si un propietario enemigo transfiere colectivamente más fuerza que el propietario original (y todos los demás atacantes), ese enemigo se convierte en el nuevo propietario. La fuerza de ese nodo se convierte en la fuerza del atacante. Si hay un empate para la fuerza, entonces el propietario será elegido al azar.
  4. Todos los nodos que queden sin fuerza se considerarán seguros y otorgan 1 punto al propietario.

Después de 100 juegos de 100 turnos, gana el propietario con los nodos más seguros en todos los juegos. EDITAR: lo cambié de 2000 a 100 turnos, ya que terminó siendo inútil los últimos 1900 turnos

IO

Se le pasará la lista de nodos activos (a través de argumentos de línea de comando) como el siguiente:

F20 F4 E7 E2 E20 F2

Fdesigna que el nodo es un nodo amigo y Edesigna que el nodo es un enemigo.

Para cada uno de sus nodos amigos, debe devolver una acción (a través de STDOUT) como la siguiente:

0,0 1,3 5,0

Lo anterior significaría que desea aumentar su fuerza del primer nodo, usar su segundo nodo para atacar al cuarto nodo, y su último nodo transferirá su fuerza al primer nodo (y si nadie lo ataca, se convertirá en un nodo seguro )

Después de regresar, su programa debería salir.

Marcador

acumulador consiguió 3240 puntos

elegante consiguió 2370 puntos

dumbot consiguió 2262 puntos

random_bot obtuvo 1603 puntos

smarter_random_bot obtuvo 1319 puntos

steady_bot obtuvo 1097 puntos

El controlador se puede encontrar aquí: https://github.com/nathanmerrill/NetAttack

Nathan Merrill
fuente
El controlador contradice la especificación: "Si un propietario enemigo transfiere colectivamente más fuerza que el propietario original ...". Actualmente es igual o más .
randomra 01 de
@randomra: en la especificación dice: Si hay un empate para la fuerza, entonces el propietario será elegido al azar
Nathan Merrill
@NathanMerrill Supuse que los atacantes empataban.
randomra 01 de
El último nodo restante está atascado esperando hasta el final del juego, ¿verdad? ¿No hay forma de que huya?
aebabis
@acbabis correcto, pero en realidad lo pruebo y termino el juego prematuramente en ese punto.
Nathan Merrill

Respuestas:

5

Acumulador, Python

¡Vamos a empezar esta fiesta! Mi envío debería funcionar tanto en Python 2 como en Python 3.

import sys

inputs = [(i, x[0], int(x[1:])) for (i, x) in enumerate(sys.argv[1].split())]

own_nodes = sorted([(s,i) for (i,o,s) in inputs if o == 'F'])
targets = sorted([(s,i) for (i,o,s) in inputs if o == 'E'])

if targets:
    t_copy = targets[:]
    out = ""
    total_str = 0
    attackers = []
    for (s,i) in own_nodes:
        attackers += [i]
        if t_copy:
            total_str += s
            if t_copy[0][0] < total_str - 1:
                j = max([j for j in range(len(t_copy)) if t_copy[j][0] < total_str - 1])
                out += " ".join([str(k) + "," + str(t_copy[j][1]) for k in attackers]) + " "
                attackers = []
                total_str = 0
                t_copy = t_copy[:j] + t_copy[j+1:]
    if attackers:
        if t_copy:
            out += " ".join([str(k) + "," + str(t_copy[0][1]) for k in attackers])
        else:
            out += " ".join([str(k) + "," + str(attackers[0]) for k in attackers])
else:
    out = " ".join([str(i) + "," + str(own_nodes[0][1]) for (s,i) in own_nodes])

print(out.rstrip())
sys.stdout.flush()

La idea es realmente simple. Comienzo a enumerar mis nodos en orden ascendente de fuerza, manteniendo una suma de las fortalezas. Cuando la suma excede la fuerza del nodo enemigo más débil (+1 por un posible aumento), ataco ese nodo y lo elimino del grupo, restablezco la suma y continúo. Al final, si los nodos más fuertes no pueden encontrar a nadie para atacar, obtendrán más fuerza.

EDITAR: el acumulador ahora es un poco más inteligente. En lugar de atacar siempre al nodo enemigo más débil, acumula la fuerza hasta que pueda hacerlo, y luego ataca al nodo libre más fuerte que pueda con esa fuerza. Además, si todavía quedan enemigos al final, los nodos no asignados atacarán al enemigo restante más débil, en caso de que decida transferir su fuerza.

Zgarb
fuente
4

Con clase, Python3

import random, sys
f,e,p=[],[],[]
for si,s in enumerate(sys.argv[1].split()):
    if s[0]=='F': f+=[(int(s[1:]),si)]
    else: e+=[(int(s[1:]),si)]
f=sorted(f,key=lambda t:t[0]);r=4
f1,f2,f3=f[:len(f)//r],f[len(f)//r:len(f)//r*2],f[len(f)//r*2:]
for fa in f3:
    ea=[t for t in e if t[0]<fa[0]]
    p+=[(fa[1],random.choice(ea)[1])] if ea else [(fa[1],fa[1])]
for fd,fs in zip(f1,reversed(f2)):
    p+=[(fs[1],fd[1])]
    p+=[(fd[1],fd[1])]
if len(e)==0: p=[(fe[1],0) for fe in f]
for t in p: print(t[0],',',t[1],' ',sep='',end='')
sys.stdout.flush()

El bot divide sus propios nodos en 3 categorías según la fuerza y ​​cada nodo actúa de acuerdo con su categoría.

  • Cada nodo fuerte ataca un nodo enemigo aleatorio que puede vencer.
  • Cada nodo medio admite su par de nodos débiles.
  • Cada nodo débil se soporta a sí mismo.

Resultado contra el acumulador y los dos bots de muestra:

smarter_random_bot got 1301 points
random_bot got 1841 points
Accumulator got 2178 points
Classy got 2580 points
randomra
fuente
2

Dumbot, Nodejs

var input = process.argv.splice(2);
var regexp = new RegExp(" ", "gm");
input = String(input).split(regexp);
var nodes = [];
var targets = [];
for(var i = 0; i < input.length; i++){
    if(input[i].charAt(0) == "F")
        nodes.push(i);
    else
        targets.push(i);
}
var result = "";
var length = nodes.length;
for(var i = 0; i < length; i++){
    if(targets.length>0)
        result += nodes.shift() + "," + targets.shift() + " ";
    else
        result += nodes.shift() + ",0 ";
}
console.log(result);

El bot atacará sin ningún pensamiento o estrategia. El objetivo principal es garantizar una gran cantidad de nodos seguros desde el principio. Tenga en cuenta que este bot crea un bucle infinito con acumulador.

Golpear
fuente
2

SteadyBot, Node.js

(new Promise(function(resolve, reject) {
    var input = process.argv[2];
    if(input) {
        resolve(input);
    } else {
        process.stdin.once('data', function(data){
            resolve(data.toString());
        });
    }
})).then(function(input) {
    return input.trim().split(' ');
}).then(function(nodes) {
    var friends = [], enemies = [];
    nodes.forEach(function(value, index) {
        var data = { index: index, strength: parseInt(value.substring(1)) };
        if(value[0] === 'F') {
            friends.push(data);
        } else {
            enemies.push(data);
        }
    });

    function weaknessCompare(a, b) {
        return (a.strength > b.strength) ? -1 : ((a.strength < b.strength) ? 1 : 0);
    }

    friends.sort(weaknessCompare);
    enemies.sort(weaknessCompare);

    if(enemies.length === 0) {
        friends.forEach(function(friend) {
            friend.target = 0;
        });
    } else {
        if(friends.length > 0) {
            var strongest = friends[0];
            for(var i = 0; i < enemies.length; i++) {
                var enemy = enemies[i];
                if(enemy.strength + 1 < strongest.strength) {
                    strongest.target = enemy.index;
                    break;
                }
            };
        }
        if(friends.length > 1) {
            friends[1].target = friends[friends.length - 1].index;
        }
    }

    console.log(friends.map(function(friend) {
        return friend.index + ',' +
                (typeof friend.target === 'number' ? friend.target : friend.index);
    }).join(' '));
});
  • Asume que los enemigos no reforzarán los nodos grandes: el nodo amigo más grande ataca al enemigo más fuerte que puede vencer bajo esta suposición.
  • Asume que el objetivo más débil será atacado: el segundo nodo amigo más grande se mueve al nodo amigo más débil en cada ronda.
  • Quiere mucha fuerza libre: otros nodos esperan.
aebabis
fuente
No estoy seguro de por qué, pero este bot no regresa correctamente (imprime una cadena vacía). El otro bot de nodejs funciona, por lo que recomiendo echarle un vistazo. También debo mencionar que acabo de instalar nodejs, y aunque conozco JavaScript, es posible que me falte algo específico de nodejs.
Nathan Merrill
Gracias por el aviso. Cuando lo hago node SteadyBot.js F20 F4 E7 E2 E20 F2, me funciona. ¿Podría decirme la entrada por la que está fallando?
aebabis
@NathanMerrill Lo reescribí para que también funcione con stdin. Espero que eso lo arregle. cat F20 F4 E7 E2 E20 F2 | node SteadyBot.js
aebabis
@acbabis La entrada se da como un gran argumento.
randomra
@acbabis randomra es correcto. Obtendrá 1 argumento grande, la lista (a menos que reciba la llamada también como C ++, en cuyo caso, obtendrá 2).
Nathan Merrill